如何强制TreeTagModel子类实现指定方法且不增加代码冗余?
最优实现方案:非泛型基层 + 泛型CRTP中间层
这个方案完全兼容你原有代码的传递逻辑,同时强制所有子类必须实现对应类型的ResetIfSameAsRestoreModel方法,不需要修改原有传递TreeTagModel的业务代码。
核心实现步骤
- 保留原有非泛型
TreeTagModel基类,原有全链路传递、类型判断逻辑完全不用修改:
public abstract class TreeTagModel : AnotherBaseModel { // 原有基类的公共属性、逻辑都保留在这里 // 可选:新增非泛型Reset入口,对外统一调用 public abstract bool ResetIfSameAsRestoreModel(object restoreModel); // 可选:将构造函数设为private protected,禁止外部直接继承该类,强制子类必须走泛型中间层 private protected TreeTagModel(){} }
- 新增泛型中间层实现CRTP约束,仅用于强制子类实现对应类型的Reset方法,对上层业务透明:
// 泛型中间层,所有业务子类必须继承该类,自动约束实现对应类型的Reset方法 public abstract class ResetableTreeTagModel<T> : TreeTagModel where T : ResetableTreeTagModel<T> // CRTP约束,确保泛型参数就是子类自身类型 { // 强制子类实现同类型参数的Reset逻辑 protected abstract bool ResetIfSameAsRestoreModel(T restoreModel); // 实现基类的非泛型Reset入口,自动处理类型校验 public override bool ResetIfSameAsRestoreModel(object restoreModel) { if (restoreModel is T typedRestoreModel) { return ResetIfSameAsRestoreModel(typedRestoreModel); } return false; } }
- 业务子类仅需继承泛型中间层,和原有实现逻辑几乎无差别:
public class FordModel : ResetableTreeTagModel<FordModel> { protected override bool ResetIfSameAsRestoreModel(FordModel restoreModel) { // 业务实现逻辑 return true; } } public class ChevyModel : ResetableTreeTagModel<ChevyModel> { protected override bool ResetIfSameAsRestoreModel(ChevyModel restoreModel) { // 业务实现逻辑 return true; } }
优势说明
- 原有代码中所有使用
TreeTagModel作为参数、存储到树形结构的逻辑完全不需要修改,类型判断依然可以用if(curTreeModel is FordModel ford)的原生语法,没有额外复杂度 - 所有业务子类自动被约束必须实现自身类型的
ResetIfSameAsRestoreModel方法,不会出现类型不匹配的问题 - 对外调用Reset方法无需判断类型,直接调用
anyTreeTagModel.ResetIfSameAsRestoreModel(restoreObj)即可,类型不匹配自动返回false,无异常风险
内容的提问来源于stack exchange,提问作者Siberian
相关产品推荐
相关产品推荐

