When and why would you seal a class?

I think this post has some good point, the specific case was when trying to cast a non-sealed class to any random interface, compiler doesn't throw error; but when sealed is used the compiler throws error that it can't convert. Sealed class brings additional code access security.
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla


Marking a class as Sealed prevents tampering of important classes that can compromise security, or affect performance.

Many times, sealing a class also makes sense when one is designing a utility class with fixed behaviour, which we don't want to change.

For example, System namespace in C# provides many classes which are sealed, such as String. If not sealed, it would be possible to extend its functionality, which might be undesirable, as it's a fundamental type with given functionality.

Similarly, structures in C# are always implicitly sealed. Hence one cannot derive one structure/class from another structure. The reasoning for this is that structures are used to model only stand-alone, atomic, user-defined data types, which we don't want to modify.

Sometimes, when you are building class hierarchies, you might want to cap off a certain branch in the inheritance chain, based on your domain model or business rules.

For example, a Manager and PartTimeEmployee are both Employees, but you don't have any role after part-time employees in your organization. In this case, you might want to seal PartTimeEmployee to prevent further branching. On the other hand, if you have hourly or weekly part-time employees, it might make sense to inherit them from PartTimeEmployee.


  1. On a class that implements security features, so that the original object cannot be "impersonated".

  2. More generally, I recently exchanged with a person at Microsoft, who told me they tried to limit the inheritance to the places where it really made full sense, because it becomes expensive performance-wise if left untreated.
    The sealed keyword tells the CLR that there is no class further down to look for methods, and that speeds things up.

In most performance-enhancing tools on the market nowadays, you will find a checkbox that will seal all your classes that aren't inherited.
Be careful though, because if you want to allow plugins or assembly discovery through MEF, you will run into problems.


An addendum to Louis Kottmann's excellent answer:

  1. If a class isn't designed for inheritance, subclasses might break class invariants. This really only applies if you're creating a public API, of course, but as I rule of thumb I seal any class not explicitly designed to be subclassed.

On a related note, applicable to unsealed classes only: any method created virtual is an extension point, or at least looks like it should be an extension point. Declaring methods virtual should be a conscious decision as well. (In C# this is a conscious decision; in Java it isn't.)

And then there's this:

  1. Sealing can make unit testing more difficult, as it prohibits mocking.

Some relevant links:

  • Effective Java, 2nd Edition by Joshua Bloch. See item 17 (requires Safari subscription)
  • Effective Java Item 17: Design and document for inheritance or else prohibit it (discussion of same item)

Also note that Kotlin seals classes by default; its open keyword is the opposite of Java's final or the sealed of C#. (To be sure, there is no universal agreement that this is a good thing.)

Tags:

C#

.Net

Oop

C++ Cli