简体   繁体   English

密封一个班级

[英]Sealing a class

Sealing a class is not something I have taken much notice of in the past however I find myself wondering what is the best practice. 密封课程不是我过去常常注意到的事情,但我发现自己想知道什么是最佳实践。 If you know a class would not or should not be derived from would you seal it as a matter of precaution of just leave the sealed keyword out knowing that the chances of someone trying to derive from it are slim. 如果你知道一个课程不会或不应该从中得出你是否会密封它作为一个预防措施,只需留下密封的关键字,知道有人试图从中获取的机会很小。

I guess what I am asking is should you seal all classes which are not intended for inheritance just as a matter of good practice? 我想我要问的是,你是否应该密封所有不用于继承的课程,只是作为一种良好的做法?

If you follow the open/closed principle to the letter, the sealed keyword should never be used. 如果您遵循开放/封闭原则,则不应使用sealed关键字。 But I guess there are always corner cases. 但我想总有一些案例。

In application code, where all code that derives from your class is controlled by yourself, I'd leave most classes unsealed by default. 在应用程序代码中,从您的类派生的所有代码都是由您自己控制的,我会默认将大多数类保持为未密封。 If you break code deriving from your class by changing the base class, you can simply fix it. 如果您通过更改基类来破坏从您的类派生的代码,您可以简单地修复它。

But sealing is very useful in library code. 但是密封在库代码中非常有用。 If you leave a class unsealed, you promise to not break any code that derives from it. 如果您保持一个未密封的类,您承诺不会破坏从中派生的任何代码。 ie you increase your public surface area. 即你增加你的公共表面积。 IMO libaries should keep the surface area minimal by default, which implies sealing. IMO图书馆应默认保持表面积最小,这意味着密封。

But it's not always necessary to seal the entire class. 但并不总是需要密封整个班级。 It can be enough to seal some or all virtual methods. 密封一些或所有虚拟方法就足够了。 That way code that derives from your class can only extend it, but not modify its current functionality by overriding a method. 这样,从您的类派生的代码只能扩展它,但不能通过覆盖方法来修改其当前功能。

Another kind of class that should often be sealed classes with value semantics. 另一种类通常应该是具有值语义的密封类。 It's much harder to implement correct equality and pseudo mutators for unsealed classes. 为未密封的类实现正确的相等和伪变异器要困难得多。 So I'd simply seal them and avoid the additional work unless really necessary. 因此,除非确实有必要,否则我只需密封它们并避免额外的工作。

I'm not going to give you a straight answer, but here are some things to consider: 我不打算给你一个直接的答案,但这里有一些事情需要考虑:

Sealed classes might give you a (slight) performance benefit. 密封类可能会给您带来(轻微)性能优势。 See this thread: 看到这个帖子:

Do sealed classes really offer performance Benefits? 密封课真的提供性能优势吗?

Sealed classes often interfere with common mocking frameworks which are implemented by subclassing your code. 密封类通常会干扰通过子类化代码实现的常见模拟框架。

For further reading: 进一步阅读:

Why does the 'sealed' keyword exist in .Net? 为什么.Net中存在'sealed'关键字?

In practice, I often don't seal classes. 在实践中,我经常不上课。

You should not arbitrarily seal all classes that are not, at any given time, meant to be inherited from. 你不应该随意密封所有在任何特定时间都没有继承的类。

Instead, seal classes that you know should NEVER be inherited from and leave the others open. 相反,你知道的密封类不应该继承而是让其他人保持开放状态。 If, at some later point in time, a decision can be made that those classes should NEVER be inherited from you can seal them then. 如果在某个以后的某个时间点,可以决定不应该继承这些类,那么就可以将它们封存起来。

The only time I notice a class is sealed is when I really need to derive something from it, but then find out that I can't. 我注意到课程被密封的唯一一次是我真的需要从中得到一些东西,但后来发现我不能。

I've never felt the need to seal my own classes. 我从来没有觉得需要密封自己的课程。 I simply don't think I'm smart enough to know when a class should never be derived. 我根本不认为我足够聪明,知道什么时候不应该派生一个班级。 I'm pretty clever, but I can't tell the future. 我很聪明,但我不能告诉未来。

For core .NET Framework classes to be sealed may make some sense so that they can tightly control the behavior of the framework, but I'v never seen a case where a everyday developer would need to do this. 对于要密封的核心.NET Framework类可能有一定意义,以便他们可以严格控制框架的行为,但我从未见过日常开发人员需要这样做的情况。 You may want to discourage deriving a class, but sealing it is pretty final, and who knows what your needs will be next week/month/year/lifetime? 您可能希望不鼓励派出一个班级,但是密封它是非常最终的,谁知道您的需求将在下周/月/年/终身?

Yes, if you want that your class couldn't be inherited you just add the "Sealed" keyword. 是的,如果您希望无法继承您的课程,只需添加“密封”关键字即可。 This class cannot be abstract, can't have protected or virtual methods/fields. 这个类不能是抽象的,不能有protected或virtual方法/字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM