为什么静态类是密封的?

7

我知道什么是静态类和密封类,我经常使用扩展方法,我只是想知道 - 有人知道为什么C#中的静态类是sealed吗?

我查看了MSDN和C#语言规范,但它从来没有真正说明为什么它们是sealed。

我们为什么不能继承静态类并覆盖静态成员等呢?

编辑:

感谢您的答案,但您仍在谈论静态类的定义。我知道为什么我不能重写它的方法。但我想知道为什么要这样设计?

vtables真的那么昂贵吗?为什么设计一种语言使得静态类完全静态?这只是出于传统惯例吗?还有其他优势吗?

(我有一种隐约的感觉,我可能从根本上误解了静态类的用途。)


你不能覆盖任何静态成员,即使类不是静态的;你只能遮蔽它们...为什么不使用像单例这样的设计模式,其中你可以重写成员(因为它是一个静态实例,而不是类)或其他设计模式呢? - Brian Mains
@BrianMains 这不是一个单例,而是一个零例。它从来没有任何实例,而不是只有一个。 - Servy
1
@Servy 我相信Brian建议OP使用单例模式,而不是说静态类就是单例模式。 - DavidG
1
从静态类继承没有意义。因为它没有实例,你不需要动态分派。你必须在编译时知道要调用哪个方法。 - Blorgbeard
这个为什么静态类要声明为sealed解释了原因...但是你的问题似乎更多地关注为什么不允许继承,所以并不完全重复。 - Alexei Levenkov
@BrianMains,你说得对,现在我仔细看Singleton,那可能是我想要的——一个静态对象而不是一个静态类。 - Sam Porch
2个回答

9

你无法继承静态类,因为你无法重写静态成员。你无法重写静态成员,因为重写成员的整个概念依赖于隐式参数类型的虚拟派发,而静态成员没有可派发的隐式参数。


1
你能详细解释一下“虚拟分派”吗?我可以通过谷歌搜索来避免显得无知,但只是想问问。 - RadioSpace
@RadioSpace 这是一个相当复杂的主题。如果你想了解更多,可以在谷歌上搜索一下。这已经超出了 SO 回答的范围。 - Servy
对我来说足够好了。谢谢。我大多数时候只是浏览术语然后去谷歌搜索。 - RadioSpace
是的,我同意那是字面上的答案。但是,我正在问一个更广泛的问题——你知道为什么他们这样做吗?为什么不在静态类中包含虚函数表?我是否错过了一些优势? - Sam Porch
@SamPorch 你期望他们在什么上分派呢?实例方法使用其隐式参数的类型作为查找表中的键。静态方法没有这样的参数,那么你期望他们使用什么作为键呢? - Servy
@Servy,是的,我现在明白你的意思了,静态类必须被密封,因为没有实例可以作为虚函数表的基础。非常感谢。 - Sam Porch

5
封装一个类意味着您不能将其用作超类。将类设置为static使它们无法用作基类,因为它们不能具有可重写方法。因此,从静态类派生的价值存疑:人们可以认为您可以共享来自静态基础的受保护方法,但是这是“单行道”,因为派生类不能通过提供有用的覆盖来更改其基类的功能。
这将静态类的实用性归结为方法及其相关静态数据的类似命名空间的持有者。让此类继承其他静态类将使此目的不太清晰,同时在功能或便利方面增加了很少的内容。

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