RuntimeHelpers.使用Func调用PrepareMethod时不工作;在泛型类中创建
本文关键字:工作 泛型类 创建 PrepareMethod Func 使用 string 调用 RuntimeHelpers | 更新日期: 2023-09-27 18:05:44
我目前正在开发Moq框架的扩展,以模拟非虚拟方法的实现。我目前已经通过获得原始方法的方法句柄并将其与用户定义的Func的指针交换来实现此工作。
我仍然遇到的一个问题是,当我在Moq内部代码中创建函数(在使用泛型的类中)时,我遇到了RuntimeHelpers.PrepareMethod的问题。(在执行指针交换之前,需要准备好Func)。
当我在一个普通类(例如Program)中创建完全相同的Func时,一切正常。
进一步调查这个问题可以追溯到调用类是否有泛型参数。
抛出异常:
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: The given generic instantiation was invalid.
我已经在以下代码块中隔离了这个问题:
class Program
{
static void Main(string[] args)
{
new WithoutGeneric().GoExecute();
new WithGeneric<string>().GoExecute();
}
}
public class WithoutGeneric
{
public void GoExecute()
{
//Works fine
StaticMethods.PrepareThisFunc(() => "Test");
}
}
public class WithGeneric<T>
{
public void GoExecute()
{
//Breaks
StaticMethods.PrepareThisFunc(() => "Test");
}
}
public static class StaticMethods
{
public static void PrepareThisFunc(Func<string> theFunc)
{
RuntimeHelpers.PrepareMethod(theFunc.Method.MethodHandle);
}
}
我也看了当前的开源CoreCLR代码,但还没能找出问题可能是什么。
CoreCLR:https://github.com/dotnet/coreclr/blob/master/src/vm/reflectioninvocation.cpp
异常被抛出在以下行:2435、2444、2447
有人知道如何解决这个异常吗?
CLR对于WithGeneric
类中的类型参数是未知的,它需要知道这些参数才能创建调用图。
这样做将解决问题:
class Program
{
static void Main(string[] args)
{
new WithoutGeneric().GoExecute();
new WithGeneric<string>().GoExecute();
}
}
public class WithoutGeneric
{
public void GoExecute()
{
//Works fine
StaticMethods.PrepareThisFunc1(() => "Test");
}
}
public class WithGeneric<T>
{
public void GoExecute()
{
//Works fine
StaticMethods.PrepareThisFunc2(() => "Test");
}
}
public static class StaticMethods
{
public static void PrepareThisFunc1(Func<string> theFunc)
{
RuntimeHelpers.PrepareMethod(theFunc.Method.MethodHandle);
}
public static void PrepareThisFunc2(Func<string> theFunc)
{
RuntimeHelpers.PrepareMethod(theFunc.Method.MethodHandle, new[] { typeof(string).TypeHandle });
}
}