You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过反射API正确调用MemoryMarshal.CreateSpan方法

异常原因

你写的反射调用抛错的核心原因是MemoryMarshal.CreateSpan<T>的第一个参数是ref T 托管引用参数,你直接把装箱后的结构体对象作为参数传入Invoke时,反射默认会做参数值拷贝,无法将原结构体实例的实际引用正确传递给ref形参,运行时不支持这种传参逻辑,自然抛出NotSupportedException。

实现方案

不需要unsafe关键字、不需要直接操作指针,借助反射调用Unsafe.Unbox拿到装箱值类型的内部托管引用,再依次调用CreateSpan、AsBytes方法,最后将得到的字节Span转为普通字节数组返回即可,全程不需要提前预定义对应泛型类型。

  • 注意:Span<T>是栈上的ref结构,不能直接作为object返回,必须将其内容拷贝到堆上的字节数组才能正常作为结果返回
  • 所有方法调用都通过反射动态构造泛型版本,兼容任意值类型,不需要提前知道结构体定义

完整实现代码如下:

using System.Reflection;
using System.Runtime.InteropServices;

private static byte[] GetBytes(object value)
{
    if (value == null) throw new ArgumentNullException(nameof(value));
    Type structType = value.GetType();
    if (!structType.IsValueType) throw new ArgumentException("仅支持值类型传入", nameof(value));

    // 加载需要的类型和方法
    Type mmType = typeof(MemoryMarshal);
    Type unsafeType = Assembly.Load("System.Runtime.CompilerServices.Unsafe")
        .GetType("System.Runtime.CompilerServices.Unsafe");
    BindingFlags staticPub = BindingFlags.Public | BindingFlags.Static;

    // 第一步:拿到装箱结构体内部实际存储位置的托管引用,解决ref参数传参问题
    MethodInfo unboxMethod = unsafeType.GetMethod("Unbox", staticPub).MakeGenericMethod(structType);
    object valueRef = unboxMethod.Invoke(null, new[] { value });

    // 第二步:反射调用CreateSpan创建对应结构体类型的Span
    MethodInfo createSpan = mmType.GetMethod("CreateSpan", staticPub).MakeGenericMethod(structType);
    object structSpan = createSpan.Invoke(null, new[] { valueRef, 1 });

    // 第三步:反射调用AsBytes将结构体Span转为字节Span
    MethodInfo asBytes = mmType.GetMethod("AsBytes", staticPub).MakeGenericMethod(structType);
    object byteSpan = asBytes.Invoke(null, new[] { structSpan });

    // 第四步:将栈上的Span<byte>转为堆上的字节数组返回
    MethodInfo toArray = mmType.GetMethod("ToArray", staticPub).MakeGenericMethod(typeof(byte));
    return (byte[])toArray.Invoke(null, new[] { byteSpan });
}
效果验证

传入你定义的Test结构体实例new Test { Code1 = 1, Code2 = 2 }调用上述方法,会返回长度为8的字节数组,内容为[1,0,0,0,2,0,0,0],和你直接写强类型代码得到的结果完全一致。

内容的提问来源于stack exchange,提问作者Alfonso-Rachid Huilda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 05:21:46