_Span<byte>
_ビュー(キャストの再解釈)を、コピーなし、割り当てなし、およびunsafeキーワードなしの単一の構造体値から作成するにはどうすればよいですか? 。
私は現在、安全でないキーワードを使用してのみこれを達成することができます:
_public unsafe Span<byte> AsSpan<T>(in T val) where T : unmanaged
{
void* valPtr = Unsafe.AsPointer(ref Unsafe.AsRef(val));
return new Span<byte>(valPtr, Marshal.SizeOf<T>());
}
// Alternatively, slightly easier when using 'ref' instead of 'in'
public unsafe Span<byte> AsSpan<T>(ref T val) where T : unmanaged
{
void* valPtr = Unsafe.AsPointer(ref val);
return new Span<byte>(valPtr, Marshal.SizeOf<T>());
}
_
単一の値ではなく配列を処理する場合、これはMemoryMarshal.Cast<TTo, TFrom>( ... )
を使用して簡単かつ安全に実行できます。次に例を示します。
_public Span<byte> AsSpan<T>(Span<T> vals) where T : unmanaged
{
return MemoryMarshal.Cast<T, byte>(vals);
}
_
Netstandard2.0、最新の言語バージョン_C# 7.3
_、および_System.Memory
_と_System.Runtime.CompilerServices.Unsafe
_の最新のRCパッケージを使用する:
_<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Memory" Version="4.5.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.0" />
</ItemGroup>
_
編集:メモリの安全性/破損に関する返信に関して-C#7.3で導入されたunmanaged
ジェネリック制約は、struct
ジェネリック制約を置き換えることができ、これをメモリセーフな方法で実行できます。
_
where T : unmanaged
_ type引数は参照型であってはならず、ネストのどのレベルでも参照型メンバーを含んではなりません。
部分的な解決策:
Netstandard2.0ではなくnetcoreappをターゲットにしている場合は、netcoreapp2.1で利用可能なAPIがあります(ダウンロード可能 ここ このコメント日現在)。
使用法:
using System.Runtime.InteropServices;
public Span<byte> AsSpan<T>(ref T val) where T : unmanaged
{
Span<T> valSpan = MemoryMarshal.CreateSpan(ref val, 1);
return MemoryMarshal.Cast<T, byte>(valSpan);
}
これはnotnetstandard2.0でこの機能を要求する質問の解決策です。それにもかかわらず、これはこれに遭遇する多くの人にとって役立つはずです。