【问题标题】:Reflection.Emit Generic Base Class Generic Method CallReflection.Emit 通用基类通用方法调用
【发布时间】:2010-11-27 01:39:48
【问题描述】:

我正在动态子类化具有泛型方法的泛型类型(填充它的合同)。我试图调用这个通用方法,但我生成的程序集有错误。尝试打开程序集时反射器崩溃并且此代码 sn-p 不运行。

我得到的例外是:

试图加载格式不正确的程序。 (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[] { });
    }
}

【问题讨论】:

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


    【解决方案1】:

    代替:

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

    你需要:

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

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

    【讨论】:

    • 干杯,这个答案让我解决了我遇到的更复杂的问题。该项目仍然无法正常工作,但我离我更近了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多