mar*_*ark 5 .net generics reflection.emit
想象一下以下完全合法的类型层次结构:
class A<T> where T : A<T>
{
}
class B : A<B>
{
public B():base(){}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是 A<> 的静态编译定义是否可以动态发出类型 B?
问题是如何在ModuleBuilder.DefineType
.
或者也许有另一种方法来产生这种类型,而不是
编辑:
该类型B
应该具有显式公共默认构造函数,调用从A<B>
.
您可以使用ModuleBuilder.DefineType
不指定父类型的重载,然后使用该TypeBuilder.SetParent
方法将父类型设置为递归类型(使用类似typeof(A<>).MakeGenericType(tb)
where tb
is your 之类的参数TypeBuilder
,但我在前面没有 C# 编译器我)。
编辑- 这是一个工作示例,假设您有一个ModuleBuilder mb
. 对于空的默认构造函数,您根本不需要使用该DefineConstructor
方法;或者你可以使用DefineDefaultConstructor
. 我已经包含了一个显式调用基本构造函数的示例,以防万一您想在其中添加一些额外的逻辑。
TypeBuilder tb = mb.DefineType("B");
Type AB = typeof(A<>).MakeGenericType(tb);
tb.SetParent(AB);
ConstructorInfo ctor = TypeBuilder.GetConstructor(AB, typeof(A<>).GetConstructor(new Type[] { }));
ILGenerator ilg = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { }).GetILGenerator();
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Call, ctor);
ilg.Emit(OpCodes.Ret);
Type t = tb.CreateType();
Run Code Online (Sandbox Code Playgroud)