简体   繁体   English

Reflection.Emit通用基类通用方法调用

[英]Reflection.Emit Generic Base Class Generic Method Call

I'm dynamically sub classing a generic type (filling it's contract) that has a generic method. 我动态地对具有泛型方法的泛型类型(填充它的契约)进行子类化。 I attempt to call this generic method but the assembly I produce has errors. 我试图调用这个泛型方法,但我生成的程序集有错误。 Reflector crashes when trying to open the assembly and this code snippet does not run. 尝试打开程序集时,Reflector崩溃,并且此代码段无法运行。

The exception I get is: 我得到的例外是:

An attempt was made to load a program with an incorrect format. 尝试加载格式不正确的程序。 (Exception from HRESULT: 0x8007000B) (HRESULT异常:0x8007000B)

Any help would be appreciated. 任何帮助,将不胜感激。 I'm going to install PEVerify to have a look at the generated code. 我将安装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[] { });
    }
}

Instead of: 代替:

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

You need: 你需要:

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

because testClass is an open generic class type and if you try to invoke a method it would crash. 因为testClass是一个开放的泛型类类型,如果你试图调用一个方法,它会崩溃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM