93

In C# and C++/CLI the keyword sealed (or NotInheritable in VB) is used to protect a class from any inheritance chance (the class will be non-inheritable). I know that one feature of object-oriented programming is inheritance and I feel that the use of sealed goes against this feature, it stops inheritance. Is there an example that shows the benefit of sealed and when it is important to use it?

Aan
  • 10,547
  • 30
  • 78
  • 138

4 Answers4

107
  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.

AustinWBryan
  • 2,968
  • 3
  • 17
  • 35
Louis Kottmann
  • 15,133
  • 4
  • 56
  • 85
  • why would you run into problems with MEF if using sealed class? – Erti-Chris Eelmaa Dec 12 '14 at 14:33
  • 3
    I meant be careful with sealing classes in reused libraries, especially if they're beind reused by third parties and then reintegrated (via MEF) into the codebase. Your codebase may not inherit a given class but third parties will. – Louis Kottmann Feb 12 '15 at 11:32
  • 10
    The reason #1 sounds vague but, assuming we don't write "security features" most of the time, does that mean reason #1 hardly applies? Reason #2 is for performance-tuning. How much performance difference are we talking about? Are they significant enough to justify altering a non-security class's definition? Even if the answer would be "yes", this would ideally be a compiler option i.e. "generate optimized code for all non-sealed classes", rather than having us developers to alter code base. – RayLuo May 02 '17 at 21:15
  • 1
    _it becomes expensive performance-wise if left untreated_ is this even measureable with less then an insane number of crazy tests? – t3chb0t Aug 11 '17 at 12:18
  • 6
    Sealing sucks. It makes testing harder - I would like to mock a couple ASP.NET classes with FakeItEasy, but I can't because they're sealed. – Warlike Chimpanzee Mar 10 '19 at 22:06
  • 2
    Can't agree more with @RayLuo. I hit it several times that people sealed their classes where security and performance is not really a problem. Their "sealed" simply prevented my reasonable need of overriding the classes, made things much more difficult. Like Warlike Chimpanzee said, mocking a class is so common in testing. – ZZY May 21 '19 at 02:58
  • Sealing a class could also be a good way to prevent others from modifying/extending your implementation (ie. using inheritance in order to build extra functionalities on top of your dll), but do you really care? – toughQuestions Mar 18 '20 at 13:55
  • I would agree that you should not be sealing classes unless you know what you're doing and you're having strong security/performance needs – Louis Kottmann Apr 21 '20 at 23:08
16

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:

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.)

Petter Hesselberg
  • 4,183
  • 1
  • 18
  • 35
  • 26
    Sealing classes causes more headache than benefit. I've continually found situations where developers have sealed classes, causing me hours of difficulty in what should be simple. Stop sealing classes, you're not as witty as you think you are. Seal classes only if you MUST, and even then, reconsider. Just my opinion, as the guy who has to deal with other people's sealed classes that I cannot edit/unseal. – Gant Laborde Oct 04 '16 at 20:19
  • 9
    @GantMan 's comment should actually be considered as one of the answer to the OP's question, because it essentially gives an answer as "When? Hardly. Why? This is the reason of why you do NOT do that." Grant you should re-post your comment as a separated answer and then collecting votes for it. :-) – RayLuo May 02 '17 at 21:19
  • 1
    Was this refferrng to this answer: https://stackoverflow.com/a/7777674/3195477 ? Its better to link to it than (only) name the person – StayOnTarget May 22 '20 at 13:20
2

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.

Akshay Khot
  • 2,703
  • 5
  • 24
  • 53
  • How would extending the String class be undesirable? String would still work exactly how it currently does, and you could have a derived class with additional functionality when that is desired, so what issue are you talking about? – Kevin Jan 14 '19 at 18:59
  • Also what would be the point of "capping" your inheritance hierarchy? It would mean that if you ever did need to extend that hierarchy you would have to unseal the parent class first, which is just inefficient – Kevin Jan 14 '19 at 19:00
  • 1
    Check out this [excellent post](https://blogs.msdn.microsoft.com/ericlippert/2004/01/22/why-are-so-many-of-the-framework-classes-sealed/) from Eric Lippert and this [SO question](https://stackoverflow.com/questions/35951430/why-string-is-sealed). – Akshay Khot Jan 14 '19 at 19:12
  • 1
    Even that answer basically boils down to "Why would you want to derive String?", then goes on to mention reasons why you might want to derive String (null-terminated strings for instance) and says you should just work around it without inheritance. So why make it more complicated and have to work around it later when you can simply leave it unsealed in the first place and leave your options open – Kevin Jan 14 '19 at 19:17
  • For the second question, the goal would be to prevent undesired behavior(depending on business logic). It is easier to `unseal` the class later, if needed, rather than sealing it and breaking all the classes that depend on it. – Akshay Khot Jan 14 '19 at 19:18
  • Specifically what business logic could be broken by allowing derived classes? And yes it's easier to unseal a sealed class than it is to seal an unsealed class, but that doesn't give a real reason why you might want to seal it in the first place – Kevin Jan 14 '19 at 19:20
  • Check out [this](https://stackoverflow.com/a/268287/5192528) answer from Jon Skeet. I hope that should satisfy your questions. – Akshay Khot Jan 14 '19 at 19:29
  • My inner skeptic sees an article posted in 2004 and is curious is Eric's thoughts may have evolved over the last 15 years. EDIT: Well, at least MS official stance has, per the [very link](https://stackoverflow.com/questions/268251/why-seal-a-class/268287#268287) you referenced. – chill94 Aug 29 '19 at 19:20
  • Isn't possible to get around sealed classes anyway using reflection? It is possible, for instance, to load an assembly's class and access its private members. – ATL_DEV Feb 21 '20 at 15:53
  • @ATL_DEV you probably can, but i would call that a hack. all bets are off at that point – symbiont Sep 22 '20 at 22:00
  • @symbiont Who cares, it's Microsoft. Develop for Apple you care about elegance. LOL! – ATL_DEV Sep 22 '20 at 22:02
  • @ATL_DEV i didn't deny doing it (i have actually done it before when i had no choice). i still consider what i did a hack. it doesn't have anything to do with Microsoft vs Apple. it's not about elegance either. it's common sense that you are not supposed to mess with the internals. otherwise you create Tight Coupling – symbiont Sep 23 '20 at 09:19
0

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

strisunshine
  • 359
  • 2
  • 9
  • 1
    A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](//meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](//stackoverflow.com/help/deleted-answers) – Baum mit Augen May 18 '17 at 23:16
  • Sorry I didn't intend to post it as answer, but it seems not related to other answers and I don't know where to put it – strisunshine May 19 '17 at 02:57
  • 1
    I edited the post according to the suggestion. Originally I just would like to contribute a different angle (perhaps), but I only got a downvote and we didn't talk about the content yet, could the -1 kindly let know the reason? – strisunshine May 19 '17 at 04:37