如何使用反射API调用MemoryMarshal.Createspan?

发布于 2025-02-05 16:01:12 字数 930 浏览 2 评论 0原文

假设我有此C#结构:

  public struct Test
  {
      public int Code1;
      public int Code2;
  }

此代码正常工作:

  var test = new Test { Code1 = 1, Code2 = 2 };
  var bytes = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref test, 1));

bytes中,我将获得8个字节的数组)。

现在,如何使用反射API而不是预定义/通用类型来调用相同的方法 createSpan + asbytes

我已经为createSpan part:

  private static object GetBytes(object value)
  {
      var method = typeof(MemoryMarshal).GetMethod(nameof(MemoryMarshal.CreateSpan));
      var gmethod = method.MakeGenericMethod(value.GetType());
      var parameters = new object[] { value, 1 };
      return gmethod.Invoke(null, parameters);
  }

但是在Invoke(使用相同的测试实例)上,它说:system.notsupportedexception:'指定方法不支持指定方法。'

ps:我想避免指针和Unsafe关键字。

Let's suppose I have this C# structure:

  public struct Test
  {
      public int Code1;
      public int Code2;
  }

This code works fine:

  var test = new Test { Code1 = 1, Code2 = 2 };
  var bytes = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref test, 1));

In bytes, I will get an array of 8 bytes (1, 0, 0, 0, 2, 0, 0, 0).

Now, how can I call the same methods CreateSpan + AsBytes using Reflection API instead of a predefined/generic type?

I have tried this for the CreateSpan part:

  private static object GetBytes(object value)
  {
      var method = typeof(MemoryMarshal).GetMethod(nameof(MemoryMarshal.CreateSpan));
      var gmethod = method.MakeGenericMethod(value.GetType());
      var parameters = new object[] { value, 1 };
      return gmethod.Invoke(null, parameters);
  }

But on Invoke (using the same test instance), it says: System.NotSupportedException: 'Specified method is not supported.'

PS: I would like to avoid pointers and unsafe keyword.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

手长情犹 2025-02-12 16:01:12

您无法使用反射访问span< t>,因为它不能装箱(以防止堆栈引用逃脱)。

您唯一可以做的就是创建一个通用函数,该功能可以完成您想要的所有操作,然后使用反射调用。

例如,您可以返回byte []阵列中的数组

private static byte[] GetBytes(object value)
{
    var method = typeof(ThisType).GetMethod("GetByteArray", BindingFlags.Static | BindingFlags.NonPublic);
    var gmethod = method.MakeGenericMethod(value.GetType());
    return (byte[])gmethod.Invoke(null, new object[] { value });
}

private static byte[] GetByteArray<T>(T value) where T : struct
{
    return MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan<T>(ref value, 1)).ToArray();
}

/strong>

You cannot access Span<T> using reflection because it cannot be boxed (to prevent stack references escaping).

The only thing you can do is create a generic function that does all you want it to do, then call that using reflection.

For example, you could return a byte[] array out of a generic function

private static byte[] GetBytes(object value)
{
    var method = typeof(ThisType).GetMethod("GetByteArray", BindingFlags.Static | BindingFlags.NonPublic);
    var gmethod = method.MakeGenericMethod(value.GetType());
    return (byte[])gmethod.Invoke(null, new object[] { value });
}

private static byte[] GetByteArray<T>(T value) where T : struct
{
    return MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan<T>(ref value, 1)).ToArray();
}

dotnetfiddle

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文