System.MissingMethodException: 未找到方法:'?'尝试使用委托方法构建自定义动态类型时
System.MissingMethodException: Method not found: '?' when trying to build a custom dynamic type with a delegate method
我正在尝试使用 System.Reflection.Emit
调用外部委托的方法动态构建类型。但是,当我尝试调用此方法时,我的程序崩溃并在方法调用的标题中出现异常。到目前为止,这是我的代码:
private static void TestMethodReal() => Console.Out.WriteLine("Inside TestMethod");
// In Main()
var method = typeof(Program).GetMethod(nameof(TestMethodReal), BindingFlags.Static | BindingFlags.NonPublic)!;
var builder = MyTypeBuilder.GetTypeBuilder("TestType");
var testMethod = builder.DefineMethod("TestMethod", MethodAttributes.Public, typeof(void), Type.EmptyTypes);
var generator = testMethod.GetILGenerator();
generator.EmitCall(OpCodes.Callvirt, method, null);
generator.Emit(OpCodes.Ret);
dynamic inst = Activator.CreateInstance(builder.CreateType()!)!;
inst.TestMethod(); // <--- Exception is thrown here
MyTypeBuilder
class 和 GetTypeBuilder
方法来自 this 答案,稍作修改以接受类型名称的参数。
该程序应该使用名为 TestMethod
的方法创建一个新的动态 class,该方法调用实际的 TestMethodReal
方法,实例化 class,然后调用方法。
我错过了什么?
您使用了错误的调度机制!
OpCodes.Callvirt
用于 virtual 方法调用,例如。可重写的实例方法,其解析需要推迟到运行时。
对于静态方法调用,您需要一个普通的旧 OpCodes.Call
指令:
generator.EmitCall(OpCodes.Call, method, Types.EmptyTypes);
我正在尝试使用 System.Reflection.Emit
调用外部委托的方法动态构建类型。但是,当我尝试调用此方法时,我的程序崩溃并在方法调用的标题中出现异常。到目前为止,这是我的代码:
private static void TestMethodReal() => Console.Out.WriteLine("Inside TestMethod");
// In Main()
var method = typeof(Program).GetMethod(nameof(TestMethodReal), BindingFlags.Static | BindingFlags.NonPublic)!;
var builder = MyTypeBuilder.GetTypeBuilder("TestType");
var testMethod = builder.DefineMethod("TestMethod", MethodAttributes.Public, typeof(void), Type.EmptyTypes);
var generator = testMethod.GetILGenerator();
generator.EmitCall(OpCodes.Callvirt, method, null);
generator.Emit(OpCodes.Ret);
dynamic inst = Activator.CreateInstance(builder.CreateType()!)!;
inst.TestMethod(); // <--- Exception is thrown here
MyTypeBuilder
class 和 GetTypeBuilder
方法来自 this 答案,稍作修改以接受类型名称的参数。
该程序应该使用名为 TestMethod
的方法创建一个新的动态 class,该方法调用实际的 TestMethodReal
方法,实例化 class,然后调用方法。
我错过了什么?
您使用了错误的调度机制!
OpCodes.Callvirt
用于 virtual 方法调用,例如。可重写的实例方法,其解析需要推迟到运行时。
对于静态方法调用,您需要一个普通的旧 OpCodes.Call
指令:
generator.EmitCall(OpCodes.Call, method, Types.EmptyTypes);