如何创建使用in而非ref参数的MemoryMarshal.CreateReadOnlySpan方法?
MemoryMarshal.CreateReadOnlySpan 的签名如下:
public static ReadOnlySpan<T> CreateReadOnlySpan<T> (ref T reference, int length);
注意它要求一个 ref 参数,这意味着无法按如下方式使用:
[StructLayout(LayoutKind.Sequential, Size = 512)] struct LargeStruct {} class Program { static readonly LargeStruct Blob = default; static byte GetSomethingFrom(in LargeStruct blob) { ReadOnlySpan<byte> span = MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(in blob, 1)); // ^^^^^^^ 参数为'in'但形参声明为'ref' return span[5]; } static void Main() { Console.WriteLine(GetSomethingFrom(in Blob)); } }
当然,由于 Blob 是readonly字段,无法获取它的 ref。
因此只能采用如下写法:
[StructLayout(LayoutKind.Sequential, Size = 512)] struct LargeStruct {} class Program { static readonly LargeStruct Blob = default; static unsafe byte GetSomethingFrom(in LargeStruct blob) { fixed(LargeStruct* pointer = &blob) { ReadOnlySpan<byte> span = MemoryMarshal.AsBytes(new ReadOnlySpan<LargeStruct>(pointer, 1)); return span[5]; } } static void Main() { Console.WriteLine(GetSomethingFrom(in Blob)); } }
我想知道是否可以将该行为封装为具有如下签名的方法:
public static ReadOnlySpan<T> CreateReadOnlySpan<T> (in T reference, int length);
我的尝试
以下是我目前的尝试:
using System; using System.Runtime.CompilerServices; public static class MemoryMarshal2 { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe ReadOnlySpan<T> CreateReadOnlySpan<T>(in T value, int length) where T : unmanaged { fixed(T* pointer = &value) { return new ReadOnlySpan<T>(pointer, length); } } }
但我不确定 fixed 关键字的这种用法是否恰当。文档指出:
指向可移动托管变量的指针仅在
fixed上下文中有用。
而我却通过返回的 ReadOnlySpan 将该指针“泄漏”到了 fixed 上下文之外。另外我认为上述示例中的 Blob 变量可能会被GC移动?
内容的提问来源于stack exchange,提问作者Matt Thomas
相关产品推荐
相关产品推荐

