如何用C# TypeBuilder创建继承自递归泛型父类的动态类型?
解决TypeBuilder创建递归泛型继承类型的「鸡生蛋」问题
嘿,这个问题我当初刚接触TypeBuilder时也卡了好久!其实CLR早就为这种递归泛型的场景留了口子,关键是要利用TypeBuilder本身作为未完成Type的特性来打破循环,步骤其实很清晰:
- 先创建目标类型的
TypeBuilder实例,不用急着设置父类 - 直接把这个未完成的
TypeBuilder作为泛型参数,构造出你需要的父类型(也就是GenericBase<TypeBuilder>) - 把构造好的父类型赋值给
TypeBuilder的父类 - 最后完成类型创建,CLR会自动把未完成的
TypeBuilder替换成最终的类型
下面是完整的可运行代码示例:
using System; using System.Reflection; using System.Reflection.Emit; // 你的基础泛型抽象类 public abstract class GenericBase<T> { } class Program { static void Main() { var baseGenericType = typeof(GenericBase<>); // 1. 初始化动态程序集和模块,创建目标类型的TypeBuilder(此时还没指定父类) var assemblyName = new AssemblyName("DynamicRecursiveAssembly"); var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); var moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicRecursiveModule"); var typeBuilder = moduleBuilder.DefineType( "Instantiated", TypeAttributes.Public | TypeAttributes.Class ); // 2. 构造父类型:直接用未完成的TypeBuilder作为泛型参数 var parentType = baseGenericType.MakeGenericType(typeBuilder); // 3. 给TypeBuilder设置父类型 typeBuilder.SetParent(parentType); // 4. 完成类型创建 var instantiatedType = typeBuilder.CreateType(); // 验证结果:输出父类型,确认是GenericBase<Instantiated> Console.WriteLine(instantiatedType.BaseType.FullName); } }
原理说明
TypeBuilder本身继承自Type,所以即使类型还没通过CreateType()完成创建,它也可以作为泛型参数传入MakeGenericType()。当你最终调用CreateType()时,CLR会自动处理这个引用,把未完成的TypeBuilder替换成最终生成的Type实例,完美形成Instantiated : GenericBase<Instantiated>的递归继承关系。
如果后续需要在动态类型里添加方法、属性,用到这个递归泛型的类型(比如返回Instantiated类型的方法),同样可以在CreateType()之前用TypeBuilder来引用自己,完全没问题。
内容的提问来源于stack exchange,提问作者user2882307
相关产品推荐
相关产品推荐

