Home > Mobile >  How to call MemoryMarshal.CreateSpan using Reflection API?
How to call MemoryMarshal.CreateSpan using Reflection API?

Time:06-09

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.

CodePudding user response:

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

  • Related