2014-12-02 181 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