【问题标题】:System.MissingMethodException: Method not found: '?' when trying to build a custom dynamic type with a delegate methodSystem.MissingMethodException:找不到方法:“?”尝试使用委托方法构建自定义动态类型时
【发布时间】:2022-01-27 23:26:10
【问题描述】:

我正在尝试使用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 类和GetTypeBuilder 方法来自this 答案,稍作修改以接受类型名称的参数。

这个程序应该用一个名为TestMethod的方法创建一个新的动态类,该方法调用实际的TestMethodReal方法,实例化该类,然后调用该方法。

我错过了什么?

【问题讨论】:

  • 这很奇怪BindingFlags.Static | BindingFlags.NonPublic)!;! 是干什么用的?再次出现在您的错误 Activator.CreateInstance(builder.CreateType()!)!; 之前的行中
  • 这是一个新的 C# 版本(我相信是 9.0 或 10.0)的一个有点烦人的特性。 GetMethod 返回一个可为空的 MethodInfo? 类型(注意末尾的“?”)。 ! 基本上保证了返回值不为空,否则我的 IDE 会报错并在它下面画一条难看的黄色波浪线。与CreateTypeCreateInstance 相同,分别返回可空的Type?object? 类型。
  • 直接调用目标方法而不是请求虚拟调度:generator.EmitCall(OpCodes.Call, method, Types.EmptyTypes) - 您不需要运行时为您解析TestMethodReal,因为您已经通过method 准确引用了它:)
  • 您确定您在 .NET 6 / .NET Core 上运行吗,因为链接答案中使用的 AppDomain.DefineDynamicAssembly 仅适用于 .NET Framework。
  • @GuruStron 我忘了提这个,但是那个方法的 .NET Core 替换是 AssemblyBuilder.DefineDynamicAssembly,我也在链接的 GetTypeBuilder 方法中替换了它。

标签: c# .net-core reflection.emit .net-6.0


【解决方案1】:

你使用了错误的调度机制!

OpCodes.Callvirt 用于 virtual 方法调用,例如。可覆盖的实例方法,其解析需要延迟到运行时。

对于静态方法调用,您需要一个普通的旧 OpCodes.Call 指令:

generator.EmitCall(OpCodes.Call, method, Types.EmptyTypes);

【讨论】:

    猜你喜欢
    • 2011-04-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多