2009-09-10 2 views
3

Я динамически подклассифицирую родовой тип (заполняя его контракт), который имеет общий метод. Я пытаюсь вызвать этот общий метод, но сборка, которую я выпускаю, имеет ошибки. Отражатель падает при попытке открыть сборку, и этот фрагмент кода не запускается.Reflection.Emit Generic Base Class Generic Method Call

Исключение я получаю:

Была сделана попытка загрузить программу, имеющую неверный формат. (Исключение из 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[] { }); 
    } 
} 

ответ

6

Вместо:

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

Понадобится:

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

потому что testClass является открытым универсальным типом класса, и если вы пытаетесь вызвать метод его падение будет.

+0

Приветствия, этот ответ заставил меня решить более сложную проблему, которую я имел. Проект все еще не работает, но я намного ближе. –