You need to enable JavaScript to run this app. C#中无需手动调用基类即可自动扩展方法实现统一日志记录的方案
优惠活动
大模型
产品
解决方案
定价
更多

C#中无需手动调用基类即可自动扩展方法实现统一日志记录的方案

解决基类预置逻辑被派生类重写覆盖不触发的问题

这个场景的核心问题是:C#中派生类重写虚方法时,如果不手动调用base.xxx(),基类的原有逻辑会被直接跳过。要实现基类通用逻辑强制自动执行、不需要派生类手动维护调用,最稳妥的方案是采用模板方法模式重构类结构。

实现思路

把原来带通用日志逻辑的对外入口方法(Start、Update、End)设为非虚的封闭方法,禁止派生类直接重写整个流程。在入口方法内部按固定顺序执行:

  • 先跑基类预置的统一日志逻辑
  • 再调用专门留给派生类实现业务的protected钩子方法
    从结构上保证:只要外部调用入口方法,基类的日志逻辑一定会执行,完全不依赖派生类手动写base调用。

重构后的代码

using System;

public abstract class Phase {
    // 对外暴露的统一入口,禁止派生类重写完整流程
    public void Start() {
        // 基类统一日志,无条件先执行
        Console.Write("[LOG] Start");
        // 调用派生类的业务实现
        OnStart();
    }

    /// <summary>
    /// Returns true when finished.
    /// </summary>
    public bool Update() {
        // 基类统一日志
        Console.Write("[LOG] Update");
        // 把派生类的业务返回值透传出去
        return OnUpdate();
    }

    public void End() {
        // 基类统一日志
        Console.Write("[LOG] End");
        // 调用派生类的业务实现
        OnEnd();
    }

    // 给派生类留的业务实现钩子,仅内部可访问
    protected virtual void OnStart() { }
    protected virtual bool OnUpdate() => true;
    protected virtual void OnEnd() { }
}

public class PhaseMenu : Phase {
    private byte _counter;

    // 派生类只需要重写业务钩子,完全不需要关心日志逻辑
    protected override void OnStart() {
        _counter = 0;
    }
    
    protected override bool OnUpdate() {
        _counter++;
        if ( _counter > 100 ) {
            return true;
        }
        return false;
    }

    protected override void OnEnd() {
        // 派生类自定义的End逻辑,留空也不会影响基类日志执行
    }
}

实际效果

  • 所有派生类调用对外的Start/Update/End方法时,基类的日志逻辑会自动触发,不存在漏执行的可能
  • 派生类开发者只需要聚焦自身业务逻辑,不需要记忆、手动添加base.xxx()的调用,从代码结构上避免了漏写导致的逻辑丢失
  • 后续如果需要给所有Phase子类增加统一的前置/后置逻辑(比如异常捕获、耗时统计),只需要修改基类的入口方法即可,所有派生类自动生效

针对个别需要临时跳过日志的特殊派生类,可以在基类增加可配置的布尔开关,在入口方法判断开关状态决定是否输出日志,不需要破坏整体的结构约束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.14 09:36:04