You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:58:30