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();
}