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

.NET 8运行时动态创建继承Base派生类并覆写Foo方法

实现运行时动态生成继承自T的类型并覆写Foo方法

以下是基于.NET 8的完整实现方案,通过System.Reflection.Emit在运行时动态生成继承自泛型参数T的类型,并覆写Foo方法以返回指定格式的字符串:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;

public class Base
{
    public virtual string Foo() => "From Base";
}

public class RealA : Base
{
    public override string Foo() => $"From RealA, { base.Foo()}";
}

public class RealB : Base
{
    public override string Foo() => "From RealB, " + base.Foo();
}

public static class TypeGenerator
{
    private static readonly Dictionary<Type, Type> _generatedTypesCache = new();
    private static readonly ModuleBuilder _dynamicModule;

    static TypeGenerator()
    {
        // 创建可回收的动态程序集与模块
        var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(
            new AssemblyName("DynamicFinalTypeAssembly"), 
            AssemblyBuilderAccess.RunAndCollect);
        _dynamicModule = assemblyBuilder.DefineDynamicModule("DynamicFinalTypeModule");
    }

    public static Type GetFinalType<T>() where T : Base
    {
        var baseType = typeof(T);
        
        // 缓存已生成的类型,避免重复创建
        if (_generatedTypesCache.TryGetValue(baseType, out var cachedType))
        {
            return cachedType;
        }

        // 定义继承自T的新类型
        var typeBuilder = _dynamicModule.DefineType(
            $"{baseType.FullName}_Final",
            TypeAttributes.Public | TypeAttributes.Class,
            baseType);

        // 获取Base类中Foo方法的元信息
        var baseFooMethod = typeof(Base).GetMethod(
            nameof(Base.Foo), 
            BindingFlags.Public | BindingFlags.Instance);
        
        if (baseFooMethod == null)
        {
            throw new InvalidOperationException("Base类的Foo方法未找到");
        }

        // 定义重写的Foo方法
        var fooMethodBuilder = typeBuilder.DefineMethod(
            nameof(Base.Foo),
            MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
            typeof(string),
            Type.EmptyTypes);

        var il = fooMethodBuilder.GetILGenerator();
        // 编写IL指令实现方法逻辑:调用基类Foo -> 拼接前缀 -> 返回结果
        il.Emit(OpCodes.Ldarg_0);               // 加载当前实例(this)
        il.Emit(OpCodes.Call, baseFooMethod);   // 调用基类Foo方法
        il.Emit(OpCodes.Ldstr, "From final type, "); // 加载前缀字符串
        il.Emit(OpCodes.Swap);                  // 交换栈中两个值的顺序,适配string.Concat参数
        il.Emit(OpCodes.Call, typeof(string).GetMethod(nameof(string.Concat), new[] { typeof(string), typeof(string) }));
        il.Emit(OpCodes.Ret);                   // 返回拼接后的字符串

        // 完成类型创建并缓存
        var generatedType = typeBuilder.CreateType() ?? throw new InvalidOperationException("动态类型创建失败");
        _generatedTypesCache[baseType] = generatedType;

        return generatedType;
    }
}

// 调用示例
public class Program
{
    public static void Main()
    {
        Type finalType = TypeGenerator.GetFinalType<Base>();
        Console.WriteLine(((Base)Activator.CreateInstance(finalType)).Foo());
        // 输出: From final type, From Base

        Type finalTypeA = TypeGenerator.GetFinalType<RealA>();
        Console.WriteLine(((Base)Activator.CreateInstance(finalTypeA)).Foo());
        // 输出: From final type, From RealA, From Base

        Type finalTypeB = TypeGenerator.GetFinalType<RealB>();
        Console.WriteLine(((Base)Activator.CreateInstance(finalTypeB)).Foo());
        // 输出: From final type, From RealB, From Base
    }
}

关键实现说明

  1. 缓存机制:通过静态字典缓存已生成的动态类型,避免重复创建相同类型,提升运行效率。
  2. 可回收动态程序集:使用AssemblyBuilderAccess.RunAndCollect创建可被GC回收的动态程序集,避免内存泄漏。
  3. 类型与方法定义:通过TypeBuilder创建继承自T的公共类,通过MethodBuilder定义与基类Foo签名一致的重写方法。
  4. IL指令编写:直接编写IL指令实现方法逻辑,确保调用基类Foo方法并正确拼接前缀字符串。

内容的提问来源于stack exchange,提问作者vernou

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:37:11