6

想象一下以下完全合法的类型层次结构:

class A<T> where T : A<T>
{
}

class B : A<B>
{
  public B():base(){}
}

我的问题是 A<> 的静态编译定义是否可以动态发出类型 B ?

问题是如何在ModuleBuilder.DefineType.

或者也许有另一种方法来产生这种类型,除了

  • 使用上述方法
  • 使用 CodeDom(这很像创建一个临时文件并将其传递给 csc.exe :-))

编辑: 该类型B应该具有显式的公共默认构造函数,调用从A<B>.

4

1 回答 1

7

您可以使用ModuleBuilder.DefineType未指定父类型的重载,然后使用该TypeBuilder.SetParent方法将父级设置为递归类型(使用类似于typeof(A<>).MakeGenericType(tb)where tbis 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();
于 2009-09-14T15:58:42.017 回答