Is it possible to emit a type deriving from a generic type while specifying itself as the generic type parameter?

允我心安 提交于 2019-12-12 09:41:32

问题


Imagine the following perfectly legal type hierarchy:

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

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

My question is given a statically compiled definition of A<> is it possible to emit the type B dynamically?

The problem is how to specify the parent type in ModuleBuilder.DefineType.

Or maybe there is another way to produce such a type, other than

  • using the aforementioned method
  • using CodeDom (which is much like creating a temporary file and passing it to csc.exe :-))

EDIT: The type B should have explicit public default constructor invoking the default constructor inherited from A<B>.


回答1:


You can use an overload of ModuleBuilder.DefineType which doesn't specify a parent type, and then use the TypeBuilder.SetParent method to set the parent to the recursive type (using an argument something like typeof(A<>).MakeGenericType(tb) where tb is your TypeBuilder, but I don't have a C# compiler in front of me).

EDIT - here's a working example, assuming you've got a ModuleBuilder mb. For an empty default constructor, you don't need to use the DefineConstructor method at all; alternatively you could use DefineDefaultConstructor. I've included an example where the base constructor is explicitly called, though, in case you have some extra logic you want to add in there.

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();


来源:https://stackoverflow.com/questions/1421149/is-it-possible-to-emit-a-type-deriving-from-a-generic-type-while-specifying-itse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!