C#多派生类重写基类方法时统一添加前置校验的优雅方案
最优方案:使用模板方法模式改造基类
该方案不需要修改任何派生类内部的业务逻辑代码,仅需对基类做极小调整,配合IDE全局批量替换就能完成所有改动,完全避免逐个修改100个派生类的冗余工作。
具体实现步骤
- 第一步:重构抽象基类
BaseFunction,将对外暴露的FunctionCall从抽象方法改为密封的公共非抽象方法,在该方法内部优先执行统一前置校验逻辑,校验通过后再调用一个新增的protected abstract类型的核心方法,承接派生类的业务实现。 - 第二步:通过IDE全局查找替换功能,批量将所有派生类中
public override Result FunctionCall()的方法签名替换为对应核心抽象方法的签名,方法内部的业务代码不需要做任何改动。 - (可选)如果存在个别派生类需要自定义校验规则,可以将校验逻辑抽成基类的
protected virtual方法,允许特殊派生类重写扩展。
改造后代码示例
抽象基类代码
public abstract class BaseFunction { // 统一调用入口,密封防止派生类重写绕开校验 public Result FunctionCall() { // 执行统一前置校验 if (!Validate()) { return Result.Fail("前置校验未通过"); } // 校验通过后执行业务逻辑 return ExecuteCore(); } // 派生类必须实现的核心业务逻辑,对外隐藏 protected abstract Result ExecuteCore(); // 通用校验逻辑,设为虚方法支持特殊派生类自定义 protected virtual bool Validate() { // 此处写通用校验逻辑:参数校验、权限校验、幂等判断等 return true; } }
派生类代码
所有派生类仅需替换方法签名,内部业务逻辑完全保留:
public class Function1 : BaseFunction { // 原方法签名 public override Result FunctionCall() 批量替换为以下签名即可 protected override Result ExecuteCore() { // 原有业务逻辑不需要做任何修改 } }
方案优势
- 校验逻辑完全收敛在基类,后续调整校验规则仅需修改基类一处,不会出现漏改、不同派生类校验逻辑不一致的问题
- 对外调用接口完全不变,所有原有调用
FunctionCall的代码不需要做任何适配 - 从语法层面保证校验逻辑无法被绕过:公共入口方法为密封方法,派生类无法重写,只能实现核心业务部分
- 兼容特殊场景:校验方法为虚方法,个别需要自定义校验规则的派生类可以单独重写,不影响通用逻辑
备选方案:AOP方法拦截
如果完全不想改动基类和派生类的现有代码结构,可以引入动态代理实现AOP拦截,在调用FunctionCall方法前统一执行校验逻辑。但该方案需要修改所有派生类实例化的逻辑,替换为代理生成的实例,还会引入额外的框架依赖,复杂度远高于模板方法方案,非特殊场景不优先选用。
内容的提问来源于stack exchange,提问作者AjS
相关产品推荐
相关产品推荐

