我有一个 MethodInfo
表示方法的对象,该方法采用 ref struct
作为参数,并且该结构具有 ReadOnlySpan<byte>
field 。如何通过 MethodInfo
调用该方法目的?我无法使用 MethodInfo.Invoke
因为Invoke
需要参数为 object?[]?
数组和 struct
与 ReadOnlySpan<byte>
字段不能转换为 object
.
那么如何通过反射调用方法并将其传递给 ref struct 值,其中该结构具有 ReadOnlySpan
类型的字段?
最佳答案
由于您的struct
自然会是 ref struct
它将存在于堆栈中(并且无法逃逸到托管堆),您将面临一些编译器限制并且需要克服一些障碍。
- A ref struct can't be the element type of an array.
- A ref struct can't be a declared type of a field of a class or a non-ref struct.
- A ref struct can't implement interfaces.
- A ref struct can't be boxed to System.ValueType or System.Object.
- A ref struct can't be a type argument. vA ref struct variable can't be captured by a lambda expression or a local function.
- A ref struct variable can't be used in an async method. However, you can use ref struct variables in synchronous methods, for example, in those that return Task or Task.
- A ref struct variable can't be used in iterators.
如您所见,
ref struct
不能在 heap
上装箱.这意味着您将无法转换为 object
并使用 Invoke
.但是,您可以使用表达式树或 relection.emit
使用表达式树时,您需要使用带有 Expression.Lambda
的委托(delegate)。如ref struct
不能用作 Func
中的类型参数.给定
public readonly ref struct Bob
{
public Bob(ReadOnlySpan<byte> myProperty)
=> MyProperty = myProperty;
public ReadOnlySpan<byte> MyProperty { get; }
}
...
public static byte DoSomething(Bob bob)
=> bob.MyProperty[1]; // return something from the span ¯\_(ツ)_/¯
delegate byte myDelegate(Bob asd);
...
var bytes = new byte[] {1, 2, 3};
var span = bytes.AsSpan();
var bob = new Bob(span);
用法 var method = typeof(SomeType).GetMethod("DoSomething");
var parameter = Expression.Parameter(typeof(Bob), "b");
var call = Expression.Call(method, parameter);
var expression = Expression.Lambda<myDelegate>(call, parameter);
var func = expression.Compile();
var result = func(bob);
Console.WriteLine(result);
结果2
或使用 in parameter modifier您需要使用
MakeByRefType
Returns a Type object that represents the current type when passed as a ref parameter
public static byte DoSomething(in Bob bob)
=> bob.MyProperty[1]; // return something from the span ¯\_(ツ)_/¯
delegate byte myDelegate(in Bob asd);
...
var method = typeof(SomeType).GetMethod("DoSomething", new[] {typeof(Bob).MakeByRefType()});
var parameter = Expression.Parameter(typeof(Bob).MakeByRefType(), "b");
var call = Expression.Call(method, parameter);
var expression = Expression.Lambda<myDelegate>(call, parameter);
var func = expression.Compile();
var result = func(bob);
备注 :此代码不是完美表达的堡垒,但它应该可以工作。这也是为 static
构建的方法,如果不是,则需要传入一个实例
关于c# - 如果结构具有 ReadOnlySpan 字段,如何将 ref struct 参数传递给 MethodInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63126581/