c# - Reflection.Emit 泛型基类泛型方法调用

标签 c# generics reflection code-generation reflection.emit

我正在对具有泛型方法的泛型类型进行动态子类化(填充它的契约)。我尝试调用此通用方法,但我生成的程序集有错误。尝试打开程序集时 Reflector 崩溃,此代码片段无法运行。

我得到的异常是:

试图加载格式不正确的程序。 (HRESULT 异常:0x8007000B)

如有任何帮助,我们将不胜感激。我将安装 PEVerify 以查看生成的代码。

using System;
using System.Reflection;
using System.Reflection.Emit;

public class TestClass<TFirst>
{
    public void TestMethod<TSecond>()
    {
        Console.WriteLine("It works");
    }
}
public class Program
{
    static void Main(string[] args)
    {
        // create a dynamic assembly and module 
        var assemblyName = new AssemblyName("DynamicAssembly");
        var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        var module = assemblyBuilder.DefineDynamicModule("DynamicAssembly.dll");

        // public class Voodoo.Dynamic.Class : TestClass<object>
        var testClass = typeof(TestClass<>);
        var testClassOfObject = testClass.MakeGenericType(typeof(object));
        var typeBuilder = module.DefineType(
            "Voodoo.Dynamic.Class",
            TypeAttributes.Public | TypeAttributes.Class,
            testClassOfObject);

        // public void Run()
        var methodBuilder = typeBuilder.DefineMethod("Run", MethodAttributes.Public);

        // this.TestMethod<int>();
        var testGeneric = testClass.GetMethod("TestMethod").MakeGenericMethod(typeof(int));
        var il = methodBuilder.GetILGenerator();
        il.Emit(OpCodes.Ldarg_0); // load this
        il.Emit(OpCodes.Call, testGeneric);
        il.Emit(OpCodes.Ret);

        // bake it
        var classType = typeBuilder.CreateType();

        assemblyBuilder.Save("DynamicAssembly.dll");

        // var instance = new Voodoo.Dynamic.Class();
        var instance = Activator.CreateInstance(classType);

        // instance.Run();
        classType.GetMethod("Run").Invoke(instance, new object[] { });
    }
}

最佳答案

代替:

var testGeneric = testClass
    .GetMethod("TestMethod")
    .MakeGenericMethod(typeof(int));

你需要:

var testGeneric = testClassOfObject
    .GetMethod("TestMethod")
    .MakeGenericMethod(typeof(int));

因为 testClass 是一个开放的通用类类型,如果您尝试调用一个方法,它会崩溃。

关于c# - Reflection.Emit 泛型基类泛型方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1403447/

相关文章:

c# - UWP:具有默认值 ThemeResource 的 DependencyProperty

c# - 无法创建变量类型 'Item' 的实例,因为它没有 new() 约束

java - 如何重新绑定(bind)通配符?

java - 如何从Java中的其他类读取私有(private)字段的值?

c# - 从 C# 中的对象中清除所有字符串成员

c# - 如何使用 Webdriver 和 C# 通过 Selenium 定位并单击嵌套在多个框架和框架集中的元素

java - 如何使用 JTS 或 NTS 找到曲线角点?

c# - FirebirdSql (C#) 比在 FlameRobin 中执行脚本慢

对具有无界通配符类型的方法参数使用泛型 lambda 的 Java 编译错误

java - 在 Android Q 中无法从 "android.location.ILocationManager"找到方法 reportLocation()