views:

1169

answers:

6
+17  Q: 

Why seal a class?

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 but just being evil?

+12  A: 
  • 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.

CVertex
Glad to see they clearly say "use with caution" now... wish they would practice what they preach though.
mmiika
That looks like bad advice to me :(
Jon Skeet
I don't have an opinion, it's not my advice. C# gives you control - which is okay.I've never ran into an issue with sealed classes (i.e. having the need to derive from one). If I did, I'd just wrap the sealed class instead.
CVertex
@CVertex: Sorry, I wasn't trying to criticize you - just the article.
Jon Skeet
+2  A: 

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

bruno conde
Would be interesting to see what kind of performance benefit they are talking about...
mmiika
+19  A: 

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.

Jon Skeet
Hmm.. if you extend a class, isn't it your problem if you break it?
mmiika
What if an implementation change you have no control over in the base class breaks you? Whose fault is that? Inheritance introduces fragility, basically. Favouring composition over inheritance promotes robustness, IMO.
Jon Skeet
True. Ok, makes sense if you provide some means (separate interface perhaps) to write your own implementation for testability purposes. I've just spent one too many hour writing decorators around these classes :)
mmiika
Besides, you can favour composition even if the classes are not sealed...
mmiika
Yes, interfaces are nice - and yes, you can favour composition anyway. But if I expose an unsealed base class without thinking very carefully about it, I should expect that changes might well break derived classes. That feels like a bad thing to me. Better to seal the class and avoid breakage, IMO.
Jon Skeet
Hey Jon, your reply is very good. I am wondering if you can tell me what composition is, and where can I find more info about it? I always thought OO is inheritance, not that I used inheritance all over.
Joan Venge
@Joan: Composition is a "has-a" relationship rather than "is-a". So if you want to write a class which can act like a list in some ways, but not in others, you might want to create a class with a List<T> member variable, rather than deriving from List<T>. You'd then *use* the list to implement various methods.
Jon Skeet
+1  A: 

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

Peter Parker
The reason for String in java being final is not performance, it's security.
CesarB
A: 

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.

Edward Kmett
A: 

you will be able to fine some cool stuff about sealed class and abstract class.please refer the link http://lionalblog.blogspot.com/2010/07/class-modifiers-in-c-and-vb-sealed.html

ananda