C# “创建类型”;MyClass:OtherClass<;MyClass>;{};在运行时?
在C#中是否可以在运行时创建一个从泛型类继承的类型,其中基类的模板参数是当前正在构造的类?这很好:C# “创建类型”;MyClass:OtherClass<;MyClass>;{};在运行时?,c#,generics,reflection,runtime,C#,Generics,Reflection,Runtime,在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> { } 这可能吗 编辑-根据到目前为止
// I have this class:
public class OtherClass<T>
where T : OtherClass<T>
{ }
// I want to create this at runtime:
public class MyClass : OtherClass<MyClass>
{ }
这可能吗
编辑-根据到目前为止的回复,我尝试了以下方法:
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;
}
}
之后可以设置基类型
是的。这是可能的。请参阅namespace和TypeBuilder的方法。编辑:这是我最后的工作答案:
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);
但是你为什么要这样做?@LightStriker:因为99%的
MyClass
类型是在代码中定义的,但有一些需要在部署后创建(NHibernate模型),并且OtherClass
限制泛型类型是从OtherClass
继承的类型。我编辑了我的答案-现在可以了,没有一般性的争论例外。他已经在使用Reflection.Emit。你不理解这个问题。我已经编辑了我的帖子来包含这个。不幸的是,我得到了一个异常,MyClass
违反了T
类型的约束。
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);
var genericType = typeof(OtherClass<>).MakeGenericType(typeof(MyClass));