c# - 如果结构具有 ReadOnlySpan 字段,如何将 ref struct 参数传递给 MethodInfo

标签 c# struct reflection

我有一个 MethodInfo表示方法的对象,该方法采用 ref struct作为参数,并且该结构具有 ReadOnlySpan<byte> field 。如何通过 MethodInfo 调用该方法目的?我无法使用 MethodInfo.Invoke因为Invoke需要参数为 object?[]?数组和 structReadOnlySpan<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/

相关文章:

c# - C# 中非常基本的数据库概念

c - 返回结构和 Int 的结构

c++ - 如何按降序排序?

c - 错误: assignment to expression with array type while using selection-sort

c# - 来自委托(delegate)的 PropertyInfo

java - 如何在Java中创建通用数组?

c# - 远程调试 .NET Core Linux Docker 容器 - "the current source is different from the version built into .dll"

c# - 绘制圆时如何控制圆的大小和位置

c# - 序列化 DataAnnotations

c# - 混合 asp.net 4 和 MVC 应用程序