【发布时间】:2012-11-07 19:05:52
【问题描述】:
在 C# 中是否可以在运行时创建一个类型,该类型继承自一个泛型类,其中基类的模板参数是当前正在构造的类?这将编译得很好:
// I have this class:
public class OtherClass<T>
where T : OtherClass<T>
{ }
// I want to create this at runtime:
public class MyClass : OtherClass<MyClass>
{ }
但我不确定如何使用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<T>
where T : OtherClass<T>
{ }
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'.
【问题讨论】:
-
但是……你为什么要这样做?
-
@LightStriker:因为 99% 的
MyClass类型是在代码中定义的,但有一些需要在部署后创建(NHibernate 模型)并且OtherClass限制泛型类型是继承的类型来自OtherClass。 -
我编辑了我的答案 - 现在可以使用,没有 GenericArgument 异常。
标签: c# generics reflection runtime