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

C#运行时动态包装子类实例中重写的基类方法

运行时给重写方法注入额外逻辑的实现方案

嘿,这个需求我之前也碰到过,咱们先回顾下你的代码结构,再一步步拆解可行的实现方式:

public class ABaseClass { 
    public virtual void DoAThing() { 
        Console.WriteLine("print this base"); 
    } 
}

public class AChildClass : ABaseClass { 
    public override void DoAThing() { 
        Console.WriteLine("child override"); 
        base.DoAThing(); 
    } 
}

你想要在运行时实例化AChildClass时,给它重写的DoAThing方法(或连带基类方法逻辑)添加额外执行逻辑,下面是几种实用的方案:

方案1:装饰器模式(轻量OOP实现)

装饰器模式是最直观的方式,不用修改原有类代码,通过包装对象动态添加功能。我们可以创建一个装饰器类,继承自基类,把原子类实例包进去,在方法调用前后注入逻辑:

public class AChildDecorator : ABaseClass
{
    private readonly ABaseClass _wrappedChild;

    public AChildDecorator(ABaseClass wrappedChild)
    {
        _wrappedChild = wrappedChild;
    }

    public override void DoAThing()
    {
        // 注入前置逻辑
        Console.WriteLine("[Decorator] 准备执行DoAThing");
        
        // 调用原子类的方法
        _wrappedChild.DoAThing();
        
        // 注入后置逻辑
        Console.WriteLine("[Decorator] DoAThing执行完成");
    }
}

使用时直接包装子类实例:

var originalChild = new AChildClass();
var decoratedChild = new AChildDecorator(originalChild);

decoratedChild.DoAThing();

输出结果:

[Decorator] 准备执行DoAThing
child override
print this base
[Decorator] DoAThing执行完成

这个方案的优点是简单易懂,不需要额外框架,完全基于基础OOP特性实现,适合轻量场景。

方案2:动态代理(灵活的运行时拦截)

如果需要更通用、更灵活的注入(比如批量处理多个类,或者不想提前写装饰器),可以用动态代理库,比如Castle DynamicProxy,它能在运行时生成子类的代理类,拦截所有虚方法调用。

首先安装Castle.Core NuGet包:

Install-Package Castle.Core

然后创建一个拦截器类,实现IInterceptor接口来定义注入逻辑:

using Castle.DynamicProxy;

public class MethodInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        // 前置逻辑:比如记录方法开始执行
        Console.WriteLine($"[Proxy] 即将执行方法:{invocation.Method.Name}");
        
        // 执行原方法逻辑
        invocation.Proceed();
        
        // 后置逻辑:比如记录方法执行结束
        Console.WriteLine($"[Proxy] 方法执行完成:{invocation.Method.Name}");
    }
}

运行时生成代理实例:

var proxyGenerator = new ProxyGenerator();
var interceptor = new MethodInterceptor();

// 生成AChildClass的代理实例
var proxiedChild = proxyGenerator.CreateClassProxy<AChildClass>(interceptor);

proxiedChild.DoAThing();

输出结果:

[Proxy] 即将执行方法:DoAThing
child override
print this base
[Proxy] 方法执行完成:DoAThing

这个方案的优势是可以拦截任意虚方法,甚至能修改方法参数、返回值,非常适合做通用的切面逻辑(比如日志、性能监控、权限校验)。

方案3:子类继承(直接重写扩展)

如果你的场景允许创建AChildClass的子类,也可以直接在新子类里再次重写DoAThing,注入额外逻辑:

public class AGrandChildClass : AChildClass
{
    public override void DoAThing()
    {
        // 前置逻辑
        Console.WriteLine("[GrandChild] DoAThing执行前的额外逻辑");
        
        // 调用父类(AChildClass)的方法
        base.DoAThing();
        
        // 后置逻辑
        Console.WriteLine("[GrandChild] DoAThing执行后的额外逻辑");
    }
}

运行时直接实例化这个新子类:

var grandChild = new AGrandChildClass();
grandChild.DoAThing();

这个方案最直接,但缺点是需要提前定义子类,不能完全在运行时动态修改,适合你能提前预知注入需求的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:07:57