title: How get a Span<byte> view of a struct without the unsafe keyword
body: <p>How can a <code>Span&lt;byte&gt;</code> view (reinterpret cast) be created from a single struct value with no copying, no allocations, and <strong>without the unsafe</strong> keyword.  </p>
  
  <p>I can currently only accomplish this using the unsafe keyword:</p>
  
  <pre class="lang-cs prettyprint-override"><code>public unsafe Span&lt;byte&gt; AsSpan&lt;T&gt;(in T val) where T : unmanaged
  {
      void* valPtr = Unsafe.AsPointer(ref Unsafe.AsRef(val));
      return new Span&lt;byte&gt;(valPtr, Marshal.SizeOf&lt;T&gt;());
  }
  
  // Alternatively, slightly easier when using 'ref' instead of 'in'
  public unsafe Span&lt;byte&gt; AsSpan&lt;T&gt;(ref T val) where T : unmanaged
  {
      void* valPtr = Unsafe.AsPointer(ref val);
      return new Span&lt;byte&gt;(valPtr, Marshal.SizeOf&lt;T&gt;());
  }
  </code></pre>
  
  <hr>
  
  <p>When dealing with an array rather than a single value - this is easily and safely done using <code>MemoryMarshal.Cast&lt;TTo, TFrom&gt;( ... )</code>, for example:</p>
  
  <pre class="lang-cs prettyprint-override"><code>public Span&lt;byte&gt; AsSpan&lt;T&gt;(Span&lt;T&gt; vals) where T : unmanaged
  {
      return MemoryMarshal.Cast&lt;T, byte&gt;(vals);
  }
  </code></pre>
  
  <hr>
  
  <p>Using netstandard2.0, latest language version <code>C# 7.3</code>, and latest RC packages for <code>System.Memory</code> and <code>System.Runtime.CompilerServices.Unsafe</code>:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;PropertyGroup&gt;
     &lt;TargetFramework&gt;netstandard2.0&lt;/TargetFramework&gt;
     &lt;LangVersion&gt;7.3&lt;/LangVersion&gt;
  &lt;/PropertyGroup&gt;
  &lt;ItemGroup&gt;
     &lt;PackageReference Include="System.Memory" Version="4.5.0" /&gt;
     &lt;PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.0" /&gt;
  &lt;/ItemGroup&gt;
  </code></pre>
  
  <hr>
  
  <p>Edit: 
  Concerning the replies about memory safety/corruption - the <code>unmanaged</code> generic constraint introduced in C# 7.3 can replace the <code>struct</code> generic constraint and allow this to be done in a memory safe way. </p>
  
  <p>See: <a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters" rel="noreferrer">https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters</a></p>
  
  <blockquote>
    <p><code>where T : unmanaged</code> The type argument must not be a reference type and must not contain any reference type members at any level of nesting.</p>
  </blockquote>