在运行时创建类型“MyClass:OtherClass {}”?

在C#中是否可以在运行时创建一个inheritance自generics类的类型,其中基类的模板参数是正在构造的当前类? 这将编译正常:

// I have this class: public class OtherClass where T : OtherClass { } // I want to create this at runtime: public class MyClass : OtherClass { } 

但我不知道如何使用System.Reflection.Emit.ModuleBuilder.TypeBuilder创建MyClass

 AssemblyName asn = new AssemblyName("test.dll"); AssemblyBuilder asb = AppDomain.CurrentDomain.DefineDynamicAssembly( asn, AssemblyBuilderAccess.RunAndSave, @"D:\test_assemblies"); ModuleBuilder = modb = asb.DefineDynamicModule("test", "test.dll"); TypeBuilder tb = modb.DefineType( "test", TypeAttributes.Public | TypeAttributes.Class, typeof(MyClass)); // How to specify inheritance? // populate properties, fields, methods, etc., emit... tb.CreateType(); 

这可能吗?

编辑 – 根据目前为止的回复,我试过这个:

 public class OtherClass where T : OtherClass { } public static void CreateSimple() { AssemblyName asn = new AssemblyName("test"); AssemblyBuilder asb = AppDomain.CurrentDomain.DefineDynamicAssembly( asn, AssemblyBuilderAccess.RunAndSave, @"D:\test_asms"); ModuleBuilder modb = asb.DefineDynamicModule("test", "test.dll"); try { TypeBuilder tb = modb.DefineType( "MyClass", TypeAttributes.Public | TypeAttributes.Class); Type my = tb.CreateType(); tb.SetParent(typeof(OtherClass).MakeGenericType(my)); my = tb.CreateType(); } catch (Exception e) { throw; } } 

但得到这个例外:

 GenericArguments[0], 'MyClass', on 'MyProject.Factory+OtherClass`1[T]' violates the constraint of type 'T'. 

编辑:这是我最后的工作答案:

  AssemblyName asn = new AssemblyName("test.dll"); AssemblyBuilder asb = AppDomain.CurrentDomain.DefineDynamicAssembly( asn, AssemblyBuilderAccess.RunAndSave, @"D:\test_assemblies"); ModuleBuilder modb = asb.DefineDynamicModule("test", "test.dll"); TypeBuilder tb = modb.DefineType( "test", TypeAttributes.Public | TypeAttributes.Class); // Typebuilder is a sub class of Type tb.SetParent(typeof(OtherClass<>).MakeGenericType(tb)); var t2 = tb.CreateType(); var i = Activator.CreateInstance(t2); 

诀窍是使用参数化generics类型调用SetParent,该参数是正在构造的类型的类型构建器。


使用TypeBuilder.SetParent(类型父级)方法。

使用它时要小心,将exception抛出推迟到CreateType调用:

如果parent为null,则将Object用作基本类型。

在.NET Framework 1.0和1.1版中,如果parent是接口类型,则不会抛出exception,但在调用CreateType方法时会抛出TypeLoadException。

SetParent方法不检查大多数无效的父类型。 例如,当当前类型具有默认构造函数时,它不拒绝没有默认构造函数的父类型,它不拒绝密封类型,并且它不拒绝委托类型。 在所有这些情况下,CreateType方法抛出exception。

要构建generics类型OtherClass ,请使用MakeGenericType方法:

 var genericType = typeof(OtherClass<>).MakeGenericType(typeof(MyClass)); 

您可以在之后设置基本类型。

TypeBuilder.SetParent(类型)

是。 这是可能的。 请参见Reflection.Emit命名空间和TypeBuilder的方法。