我应该封闭所有我知道永远不应该用作基类的类吗?

56

即使没有明显的性能或安全问题,我是否应该封闭所有我知道不应该作为基类使用的类,还是这样做只会增加冗余代码?


有人说过,我也读到过:除非你知道你的客户会有支持问题,否则永远不要封闭一个类。 - cregox
4个回答

57
一个可扩展的类实现了它可以被扩展的特性 - 这是一个像类的任何其他特性一样的特性,应该像方法一样对待。所有特性都应该经过仔细思考,以确保它们满足使用该特性的客户的目标。 特性需要进行设计、实现、安全问题审查、调试、文档编写和维护。这一切都需要付出努力,而努力通常需要花费金钱。你花的是谁的钱?他们可能会对你是否应该做这个特性有意见。
基本上,你有三个选择:
1)花钱去做这个特性,这样你就有信心它是正确、强大、安全并且满足用户的需求。
2)不做以上任何事情,但仍然发布这个特性,并希望发布一个未设计、快速实现、未经测试、未记录文档、未维护、具有未知安全风险的特性不会伤害你、你的雇主或你的客户。
3)密封类。如果你发现(1)是正确的选择,再将其打开。
我认为(3)物有所值。我总是密封我编写的每个未设计为可扩展性的类。

4
Eric,这里有一个问题需要您回答。就像您必须在重写方法之前声明方法为“virtual”一样,为什么C#没有采用类似的东西来指示类可以被继承,并默认将其密封。只是好奇。 - SolutionYogi
22
@Daniel,@SolutionYogi:我希望我们当初这么做了。但实际上,我的想法并不是主流的;有很多人认为只有在有理由时才应该将类标记为sealed。我不同意;我认为只有在有理由时才应该取消封印的类。 - Eric Lippert
4
因为我认为这很棒。(如果您使用RSS阅读器阅读博客,那么您将获得未格式化的内容。) - Eric Lippert
似乎有些评论被删除了。你们指的是哪篇博客文章?Atwood 说了什么? - Sunny Milenov
3
他们所提到的我的博客文章链接是:http://blogs.msdn.com/b/ericlippert/archive/2004/01/22/61803.aspx。Jeff Atwood提到的博客文章链接是:http://www.codinghorror.com/blog/2006/12/eric-lipperts-purple-crayon.html。我的回应在这里:http://blogs.msdn.com/b/ericlippert/archive/2007/01/08/the-horror-the-horror.aspx。不幸的是,回应已不再使用紫色Lucida字体。讽刺吗? - Eric Lippert
显示剩余2条评论

14

将一个类设置为sealed并不是无用的,因为这样做会在你的代码中建立一条严格的规则:这个类不能被继承。

只有当代码是不必要和令人困惑的时候,它才是无用的。

话虽如此,有一种思路(也是简单的经验法则)认为你应该总是将所有类都标记为sealed,因为如果需要,可以轻松取消sealed的限制,但反之却不行。一些代码生成器会自动这样做。(参见Eric Lippert上面的第三个选项,它本质上说的是同样的事情。)


1
像几乎所有关于如何做事的答案一样,这取决于情况。默认情况下封闭类并仅在需要时取消封闭可能会获得一些优化。请查看:http://msdn.microsoft.com/en-us/library/ms998547.aspxhttp://dotnetperls.com/sealed-1 - Firestrand

7

我认为这并不是添加冗余代码。相反,您清晰地表达了类的意图。

类应该设计为可继承或密封。不幸的是,在C#中,默认情况下类不是密封的,因此您必须自己包含关键字。个人而言,我更喜欢使用一个关键字来明确表示类可用于继承,因为这可以防止人们将一个类用作基类,除非它被明确标记为这样。


5
是的。如果没有其他事情,这是一个标志牌,让其他人知道他们不应该再往下走了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接