Domanda

Sottocludo dinamicamente un tipo generico (compilando il suo contratto) che ha un metodo generico. Tento di chiamare questo metodo generico ma l'assemblaggio che produco presenta errori. Reflector si arresta in modo anomalo quando si tenta di aprire l'assembly e questo frammento di codice non viene eseguito.

L'eccezione che ottengo è:

Tentativo di caricare un programma con un formato errato. (Eccezione da HRESULT: 0x8007000B)

Qualsiasi aiuto sarebbe apprezzato. Ho intenzione di installare PEVerify per dare un'occhiata al codice generato.

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[] { });
    }
}
È stato utile?

Soluzione

Invece di:

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

È necessario:

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

perché testClass è un tipo di classe generico aperto e se si tenta di invocare un metodo si arresterebbe in modo anomalo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top