zon*_*17x 10 .net c# .net-core asp.net-core .net-standard
如何能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>());
}
Run Code Online (Sandbox Code Playgroud)
在处理数组而不是单个值时 - 使用MemoryMarshal.Cast<TTo, TFrom>( ... )例如以下方法可以轻松安全地完成:
public Span<byte> AsSpan<T>(Span<T> vals) where T : unmanaged
{
return MemoryMarshal.Cast<T, byte>(vals);
}
Run Code Online (Sandbox Code Playgroud)
使用netstandard2.0,最新的语言版本C# 7.3,以及最新的RC包System.Memory和System.Runtime.CompilerServices.Unsafe:
<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>
Run Code Online (Sandbox Code Playgroud)
编辑:关于内存安全/损坏的回复 - unmanagedC#7.3中引入的泛型约束可以替换struct泛型约束,并允许以内存安全的方式完成.
请参阅:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters
where T : unmanagedtype参数不能是引用类型,并且不能在任何嵌套级别包含任何引用类型成员.
部分解决方案:
如果定位目标是netcoreapp而不是netstandard2.0,则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);
}
Run Code Online (Sandbox Code Playgroud)
这不是 netstandard2.0中要求此功能的问题的解决方案。尽管如此,这对于许多偶然发现的人应该是有帮助的。
| 归档时间: |
|
| 查看次数: |
2121 次 |
| 最近记录: |