在我工作的一个大项目中,我正在考虑推荐其他程序员,如果他们没有考虑如何对他们的类进行子类化,就应该始终密封他们的类.通常情况下,经验不足的程序员从不考虑这一点.

我觉得奇怪的是,在Java和C#中,默认情况下类是非密封/非最终的.我认为密封类可以极大地提高代码的可读性.

请注意,这是我们可以随时更改的内部代码,如果出现罕见的情况,我们需要子类化.

你的经历是什么?我对这个 idea 遇到了不少阻力.人们是不是懒得打sealed

推荐答案

好的,就像其他很多人都参与进来的那样……

是的,我认为建议默认密封类是完全合理的.

This goes along with the recommendation from Josh Bloch in his excellent book Effective Java, 2nd edition:

设计继承,或禁止继承.

继承设计为hard,可以使您的实现less灵活,特别是如果您有虚方法,其中一个方法调用另一个方法.可能是超载,也可能不是.一个调用另一个must be documented的事实是,否则您不能安全地覆盖这两个方法中的任何一个-您不知道它何时被调用,也不知道调用另一个方法是否安全而不会有堆栈溢出的风险.

现在,如果您以后想更改哪个方法在以后的版本中调用哪个方法,您不能更改,您可能会 destruct 子类.因此,以"灵活性"的名义,您实际上已经使实现less灵活,并且必须更详细地记录您的实现细节.对我来说,这听起来不是个好主意.

接下来是不变性——我喜欢不变性类型.我发现它们比可变类型更容易推理.这就是为什么Joda Time API比在Java中使用DateCalendar更好的原因之一.但一个未密封的类永远不可能是不变的.如果我接受Foo类型的参数,我可能可以依赖于属性declared in 103不随时间改变,但我不能依赖对象本身不被修改——子类中可能有一个可变属性.如果该属性也被某个虚拟方法的重写所使用,请god 保佑我.挥手告别不变性的许多好处.(具有讽刺意味的是,Joda Time有非常大的继承层次 struct ——通常会说"子类应该是不可变的.Chronology的大继承层次 struct 使移植到C#时很难理解.)

最后,还有过度使用继承的问题.就我个人而言,在可行的情况下,我更喜欢构图而不是继承.我喜欢接口的多态性,我使用实现的继承——但这在我的经验中很少是很合适的.将类密封起来可以避免它们从更适合组合的地方派生出来.

编辑:关于为什么这么多框架类是密封的,我还想告诉读者Eric Lippert's blog post from 2004.有很多地方我希望.NET提供一个interface,我们可以用它来实现可测试性,但这是一个稍微不同的要求……

.net相关问答推荐

.NET Blazor-使用子组件中的处理程序方法进行双向数据绑定

Azure管道-使用.NET 8 RC2 SDK生成C#项目失败

在 .NET 7 项目上设置 Sentry 时遇到问题

仅使用 .NET GetBytes 方法转换有效字节而不创建问号

如何在 C# 中将 HTTP 发布请求发送到另一个 API?

更改列表中的值

将 Span 传递到函数时出现 F# 错误

比较 C# 中的双精度值

每第 N 个字符/数字拆分一个字符串/数字?

有没有办法以编程方式最小化窗口

将屏幕捕获为位图

C# 中的 myCustomer.GetType() 和 typeof(Customer) 有什么区别?

清除 .NET 的 StringBuilder 内容的最佳方法

如何使用 c# 仅获取目录中的文件名?

如何在 C# 中将 null 值设置为 int?

C#As的 VB.NET 类似功能

在生产环境中部署调试符号(pdb 文件)有什么风险?

.Net 中 AOP 的最佳实现是什么?

/langversion 的错误选项6无效;必须是 ISO-1、ISO-2、3、4、5 或默认值

什么时候使用 Tuple 和 KeyValuePair 比较好?