【发布时间】:2011-12-08 07:43:44
【问题描述】:
在 C# 和 C++/CLI 中,关键字 sealed(或 VB 中的 NotInheritable)用于保护类免受任何继承机会(该类将是不可继承的)。我知道面向对象编程的一个特性是继承,我觉得sealed 的使用违背了这个特性,它停止了继承。
有没有例子说明sealed 的好处以及何时使用它很重要?
【问题讨论】:
在 C# 和 C++/CLI 中,关键字 sealed(或 VB 中的 NotInheritable)用于保护类免受任何继承机会(该类将是不可继承的)。我知道面向对象编程的一个特性是继承,我觉得sealed 的使用违背了这个特性,它停止了继承。
有没有例子说明sealed 的好处以及何时使用它很重要?
【问题讨论】:
在实现安全功能的类上,使原始对象不能被“模拟”。
更一般地说,我最近与 Microsoft 的一个人交流,他告诉我他们试图将继承限制在真正有意义的地方,因为如果不加以处理,它会在性能方面变得昂贵。
sealed 关键字告诉 CLR 没有进一步查找方法的类,这加快了处理速度。
在当今市场上的大多数性能增强工具中,您都会发现一个复选框,它将密封您所有未继承的类。
不过要小心,因为如果你想通过 MEF 允许插件或程序集发现,你会遇到问题。
【讨论】:
Louis Kottmann's excellent answer 的附录:
在相关说明中,仅适用于未密封的类:virtual 创建的任何方法都是扩展点,或者至少看起来应该是扩展点。声明方法virtual 也应该是一个有意识的决定。 (在 C# 中这是一个有意识的决定;在 Java 中则不是。)
然后是这样的:
一些相关链接:
还要注意Kotlin 默认密封类; its open keyword is the opposite of Java's final or the sealed of C#。 (可以肯定的是,there is no universal agreement that this is a good thing。)
【讨论】:
将类标记为Sealed 可防止篡改可能危及安全或影响性能的重要类。
很多时候,当我们设计一个具有固定行为的实用程序类时,密封类也是有意义的,我们不想改变它。
例如,C# 中的System 命名空间提供了许多密封的类,例如String。如果不密封,则可以扩展其功能,这可能是不可取的,因为它是具有给定功能的基本类型。
同样,C# 中的 structures 始终是隐式密封的。因此,不能从另一种结构派生一个结构/类。这样做的原因是structures 仅用于对我们不想修改的独立、原子、用户定义数据类型进行建模。
有时,当您构建类层次结构时,您可能希望根据您的域模型或业务规则限制继承链中的某个分支。
例如,Manager 和 PartTimeEmployee 都是 Employees,但您在组织中的兼职员工之后没有任何角色。在这种情况下,您可能需要密封 PartTimeEmployee 以防止进一步分支。另一方面,如果你有每小时或每周的兼职员工,从PartTimeEmployee 继承他们可能是有意义的。
【讨论】:
我认为这篇文章有一些好处,具体情况是当尝试将非密封类强制转换为任何随机接口时,编译器不会抛出错误;但是当使用密封时,编译器会抛出无法转换的错误。密封类带来额外的代码访问安全性。
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla
【讨论】: