Why seal a class?

.NetPerformance

.Net Problem Overview


I'd like to hear what is the motivation behind the bulk of sealed classes in the .Net framework. What is the benefit of sealing a class? I cannot fathom how not allowing inheritance can be useful and most likely not the only one fighting these classes.

So, why is the framework designed this way and wouldn't it be unbreaking change to unseal everything? There must be another reason than just being evil?

.Net Solutions


Solution 1 - .Net

Classes should either be designed for inheritance or prohibit it. There is a cost to designing for inheritance:

  • It can pin down your implementation (you have to declare which methods are going to call which other methods, in case a user overrides one but not the other)
  • It reveals your implementation rather than just the effects
  • It means you have to think of more possibilities when designing
  • Things like Equals are hard to design in an inheritance tree
  • It requires more documentation
  • An immutable type which is subclassed may become mutable (ick)

Item 17 of Effective Java goes into more details on this - regardless of the fact that it's written in the context of Java, the advice applies to .NET as well.

Personally I wish classes were sealed by default in .NET.

Solution 2 - .Net

  • Sometimes classes are too precious and not designed to be inherited.
  • Runtime/Reflection can make inheritance assumptions about sealed classes when looking for types. A great example of this is - Attributes are recommended to be sealed for lookup runtime speed. type.GetCustomAttributes(typeof(MyAttribute)) will perform significantly faster if MyAttribute is sealed.

The MSDN article for this topic is Limiting Extensibility by Sealing Classes.

Solution 3 - .Net

It seems that the official Microsoft guidelines on sealing have evolved since this question was asked ~9 years ago, and they moved from an opt-in philosophy (seal by default) to opt-out (don't seal by default):

> X DO NOT seal classes without having a good reason to do so. > > Sealing a class because you cannot think of an extensibility scenario > is not a good reason. Framework users like to inherit from classes for > various nonobvious reasons, like adding convenience members. See > Unsealed Classes for examples of nonobvious reasons users want to > inherit from a type. > > Good reasons for sealing a class include the following: > > * The class is a static class. See Static Class Design.
> * The class stores security-sensitive secrets in inherited protected members.
> * The class inherits many virtual members and the cost of sealing them > individually would outweigh the benefits of leaving the class > unsealed.
> * The class is an attribute that requires very fast runtime > look-up. Sealed attributes have slightly higher performance levels > than unsealed ones. See Attributes. > > X DO NOT declare protected or virtual members on sealed types. > > By definition, sealed types cannot be inherited from. This means that > protected members on sealed types cannot be called, and virtual > methods on sealed types cannot be overridden. > > ✓ CONSIDER sealing members that you override. Problems that can result from introducing virtual members (discussed in Virtual Members) > apply to overrides as well, although to a slightly lesser degree. > Sealing an override shields you from these problems starting from that > point in the inheritance hierarchy.

Indeed, if you search the ASP.Net Core codebase, you will only find about 30 occurences of sealed class, most of which are attributes and test classes.

I do think that immutability conservation is a good argument in favor of sealing.

Solution 4 - .Net

I found this sentence in msdn documentation: "Sealed classes are primarily used to prevent derivation. Because they can never be used as a base class, some run-time optimizations can make calling sealed class members slightly faster."

I don't know if the performance is the only advantage of sealed classes and personally I also would like to know any other reasons ...

Solution 5 - .Net

Performance is an important factor for example, the string class in java is final(<- sealed) and reason for this is performance only. I think another important point is to avoid the brittle base class problem described in detail here: http://blogs.msdn.com/ericlippert/archive/2004/01/07/virtual-methods-and-brittle-base-classes.aspx

If you provide a framework it is important for maintainability legacy projects and to upgrade your framework to avoid the brittle base class problem

Solution 6 - .Net

Sealed is used to prevent the "brittle base class problem". I found a good article in MSDN that explains that.

Solution 7 - .Net

Sealing allows you to realize some minor performance gains. This is less true in the world of JITs and lazy pessimization than in the world of, say C++, but since .NET is not as good as pessimization as java compilers are mostly because of different design philosophies it is still useful. It tells the compiler that it can directly call any virtual methods rather than call them indirectly through the vtable.

It is also important when you want a 'closed world' for things like equality comparison. Normally once I define a virtual method, I'm pretty much hosed for defining a notion of equality comparison that really implements the idea. On the other hand, I might be able to define it for a particular subclass of the class with the virtual method. Sealing that class ensures that equality really does hold.

Solution 8 - .Net

Sealing a class makes managing disposable resources easier.

Solution 9 - .Net

To determine whether to seal a class, method, or property, you should generally consider the following two points:

•The potential benefits that deriving classes might gain through the ability to customize your class.

•The potential that deriving classes could modify your classes in such a way that they would no longer work correctly or as expected.

Solution 10 - .Net

A further consideration is that sealed classes can't be stubbed in your unit tests. From Microsoft's documentation:

> Sealed classes or static methods can't be stubbed because stub types rely on virtual method dispatch. For such cases, use shim types as described in Using shims to isolate your application from other assemblies for unit testing

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmmiikaView Question on Stackoverflow
Solution 1 - .NetJon SkeetView Answer on Stackoverflow
Solution 2 - .NetCVertexView Answer on Stackoverflow
Solution 3 - .NetOhad SchneiderView Answer on Stackoverflow
Solution 4 - .Netbruno condeView Answer on Stackoverflow
Solution 5 - .NetPeter ParkerView Answer on Stackoverflow
Solution 6 - .NetihebihebView Answer on Stackoverflow
Solution 7 - .NetEdward KmettView Answer on Stackoverflow
Solution 8 - .NetJeff DunlopView Answer on Stackoverflow
Solution 9 - .Netuser3629577View Answer on Stackoverflow
Solution 10 - .NetDave ClarkView Answer on Stackoverflow