When and why would you seal a class?
Solution 1
On a class that implements security features, so that the original object cannot be "impersonated".
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.
Solution 2
An addendum to Louis Kottmann's excellent answer:
- 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:
- 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.)
Solution 3
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 Employee
s, 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
.
Solution 4
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
Related videos on Youtube
Comments
-
Aan over 1 year
In C# and C++/CLI the keyword
sealed
(orNotInheritable
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 ofsealed
goes against this feature, it stops inheritance. Is there an example that shows the benefit ofsealed
and when it is important to use it? -
Erti-Chris Eelmaa over 9 yearswhy would you run into problems with MEF if using sealed class?
-
Louis Kottmann about 9 yearsI 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.
-
Gant Laborde over 7 yearsSealing 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.
-
RayLuo about 7 yearsThe 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 about 7 years@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. :-)
-
Baum mit Augen almost 7 yearsA link to a solution is welcome, but please ensure your answer is useful without it: add context around the link 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.
-
strisunshine almost 7 yearsSorry 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 almost 7 yearsI 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?
-
t3chb0t over 6 yearsit becomes expensive performance-wise if left untreated is this even measureable with less then an insane number of crazy tests?
-
Kevin over 5 yearsHow 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 over 5 yearsAlso 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
-
ak_rails over 5 yearsCheck out this excellent post from Eric Lippert and this SO question.
-
Kevin over 5 yearsEven 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
-
ak_rails over 5 yearsFor 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. -
Kevin over 5 yearsSpecifically 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
-
ak_rails over 5 yearsCheck out this answer from Jon Skeet. I hope that should satisfy your questions.
-
Elliott Beach about 5 yearsSealing 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.
-
ZZY almost 5 yearsCan'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.
-
chill94 over 4 yearsMy 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 you referenced.
-
ATL_DEV about 4 yearsIsn'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.
-
toughQuestions about 4 yearsSealing 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?
-
Louis Kottmann about 4 yearsI would agree that you should not be sealing classes unless you know what you're doing and you're having strong security/performance needs
-
StayOnTarget almost 4 yearsWas this refferrng to this answer: stackoverflow.com/a/7777674/3195477 ? Its better to link to it than (only) name the person
-
symbiont over 3 years@ATL_DEV you probably can, but i would call that a hack. all bets are off at that point
-
ATL_DEV over 3 years@symbiont Who cares, it's Microsoft. Develop for Apple you care about elegance. LOL!
-
symbiont over 3 years@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
-
David Klempfner over 2 years"Hence one cannot derive one structure/class from another structure". - The reason for this is actually because of arrays.
-
David Klempfner over 2 yearsCan you give an example of point 1?