《Effective C#》某些地方实在是对不起Effective这个词(II)
这次我们来关注条款20:Distinguish Between Implementing Interfaces and Overriding Virtual Functions。
条款20的解释中,作者的目标是实现一个接口,并在派生类中改变它的实现,即:
interface IMsg
{
void Message();
}

// public class MyBaseClass : IMsg
// 

// public class MyDerivedClass : MyBaseClass
// 

MyBaseClass b = new MyBaseClass();
b.Message()
MyDerivedClass d = new MyDerivedClass();
d.Message()

//output:
//MyBaseClass
//MyDerivedClass
作者提到,要实现它,有两种选择,一是在派生类中使用new关键字重新实现接口;二是在基类中public virtual void Message(),并在派生类中override。并且建议override。但是这样做很好吗?
不好。
先说new掉基类public方法有什么弊端。一般情况下,接口定义了行为,抽象类的公共方法定义了这些行为的规范。比方说完成一个功能A,中间有若干步骤(k1,k2,k3...),完成整个功能,必须按照k1,k2,k3的顺序执行。所谓的“OOD”则一般把k1,k2,k3定义成protected virtual,允许派生类override。现在,如果派生类new掉了A会有什么后果呢?能保证这些中间步骤的顺序执行?
OK,现在各位发现基类中public virtual方法也有同样的问题。所以,书中建议的方法都不好。
那么怎么做才happy一些呢?
基类使用public方法实现接口,并提供一个protected virtual的internal方法完成真正的操作,派生类只override这些方法。
最后做个总结:
1、派生类尽可能不new掉基类的public方法。如果出现这样的需求,那一定是基类的设计有问题。
2、基类所有的virtual和abstract方法应该只是protected。
3、(加上上篇提到的结论)尽可能使用抽象类,而不是直接实现接口。(这个可以仔细看看msdn,仔细看看.net framework的实现,微软就是建议这么做)
4、(补上篇结论中提到的一点)方法参数,泛型中的T都应该限制最小化。
条款20的解释中,作者的目标是实现一个接口,并在派生类中改变它的实现,即:






















不好。
先说new掉基类public方法有什么弊端。一般情况下,接口定义了行为,抽象类的公共方法定义了这些行为的规范。比方说完成一个功能A,中间有若干步骤(k1,k2,k3...),完成整个功能,必须按照k1,k2,k3的顺序执行。所谓的“OOD”则一般把k1,k2,k3定义成protected virtual,允许派生类override。现在,如果派生类new掉了A会有什么后果呢?能保证这些中间步骤的顺序执行?
OK,现在各位发现基类中public virtual方法也有同样的问题。所以,书中建议的方法都不好。
那么怎么做才happy一些呢?
基类使用public方法实现接口,并提供一个protected virtual的internal方法完成真正的操作,派生类只override这些方法。
最后做个总结:
1、派生类尽可能不new掉基类的public方法。如果出现这样的需求,那一定是基类的设计有问题。
2、基类所有的virtual和abstract方法应该只是protected。
3、(加上上篇提到的结论)尽可能使用抽象类,而不是直接实现接口。(这个可以仔细看看msdn,仔细看看.net framework的实现,微软就是建议这么做)
4、(补上篇结论中提到的一点)方法参数,泛型中的T都应该限制最小化。
posted on 2007-07-19 14:59 Nineteen@newsmth 阅读(2586) 评论(31) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决