2014-12-02 143 views
1

我想從泛型父類創建非泛型類。但我總是得到InvalidProgramException。從泛型基類型發射非泛型類型

我的基類:

public interface IServiceType{} 
public class ServiceType: IServiceType{} 
public class EntityType{} 
public class KeyType{} 

public class Base<TService,TEntity, TKey> 
{ 
    public Base(TService service) 
    { 
     Service = service; 
    } 

    public TService Service { get; set; } 
} 

類型的構造函數:

static Type CreateType(Type serviceType, Type entityType, Type keyType) 
{ 
    var assemblyName = new AssemblyName("AssName"); 
    var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); 
    var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainMod"); 

    var tb = moduleBuilder.DefineType(serviceType.Name.Substring(1)+entityType.Name, TypeAttributes.Public); 

    var baseType = typeof (Base<,,>).MakeGenericType(serviceType, entityType, keyType); 

    tb.SetParent(baseType); 

    var baseCtor = baseType.GetConstructor(new [] {serviceType}); 
    if (baseCtor == null) 
     throw new InvalidOperationException("Base type constuctor not found"); 

    var constuctor = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] {serviceType}); 

    var ilgen = constuctor.GetILGenerator(); 
    ilgen.Emit(OpCodes.Ldarg_0); 
    ilgen.Emit(OpCodes.Call, baseCtor); 
    ilgen.Emit(OpCodes.Ret); 

    return tb.CreateType(); 
} 

當我打電話調用我得到「異常已通過調用的目標引發異常。」

void Main() 
{ 
    var type = CreateType(typeof(IServiceType), typeof(EntityType), typeof(KeyType)); 
    var instance = Activator.CreateInstance(type, new ServiceType{}); 
    instance.Dump(); 
} 

我做錯了什麼?

回答

4

您需要通過this和第一個參數

var ilgen = constuctor.GetILGenerator(); 
ilgen.Emit(OpCodes.Ldarg_0); // this 
ilgen.Emit(OpCodes.Ldarg_1); // 1st parameter 
ilgen.Emit(OpCodes.Call, baseCtor); 
ilgen.Emit(OpCodes.Ret); 

普羅蒂普:始終轉儲產生IL到組件;以及與PEVerify檢查。

+1

使用tb.SetParent並在DefineType中定義基類型具有相同的效果。你建議的Emit命令解決了這個問題。非常感謝你。 – 2014-12-02 19:06:37

+0

糟糕,沒有注意到; p如果你有一個通用的遞歸類型定義,有時候這是必須的。例如'Foo:東西' – leppie 2014-12-02 19:22:57