2009-09-10 10 views
3

Je sous-classe dynamiquement un type générique (remplissant son contrat) qui a une méthode générique. Je tente d'appeler cette méthode générique mais l'assemblage que je produis a des erreurs. Reflector se bloque lors de la tentative d'ouverture de l'assembly et cet extrait de code ne s'exécute pas.Reflection.Emit Generic Base Class Méthode générique Appelez

L'exception que je reçois est:

Une tentative a été faite pour charger un programme avec un format incorrect. (Exception de HRESULT: 0x8007000B)

Toute aide serait appréciée. Je vais installer PEVerify pour avoir un aperçu du code généré.

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[] { }); 
    } 
} 

Répondre

6

Au lieu de:

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

Vous devez:

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

parce testClass est un type de classe générique ouverte et si vous essayez d'appeler une méthode, il se briserait.

+0

Bravo, cette réponse m'a amené à résoudre le problème plus compliqué que j'avais. Le projet ne fonctionne toujours pas, mais je suis beaucoup plus proche. –

Questions connexes