Why does the 'sealed' keyword exist in .Ne

2019-01-18 22:27发布

A large number of classes in the .Net framework are marked as 'sealed', preventing you from inheriting those classes with your own. Surely this goes against the nature of object orientation, where you can extend and redefine the behaviour of existing objects.

Is there a good reason for the existence of the 'sealed' keyword?

As an example, NotifyCollectionChangedEventArgs in Silverlight is sealed. I wanted to create my own version of ObservableCollection that supported AddRange and RemoveRange, but the Silverlight version of NCCEA doesn't provide a constructor that supports multiple items for the NewItems and OldItems properties, which are already defined as ILists. Usually, I'd just extend the class with my own variant that overrode the NewItems and OldItems properties, but in this case I can't and I can see no reason why that should be the case.

9条回答
何必那么认真
2楼-- · 2019-01-18 23:00

Without digging too deeply, understand that Microsoft favors sealing a class when there are potential security, maintainability or backwards-compatibility issues that it will have to deal with downstream. For example, System.String is sealed for security and performance reasons.

In this particular case, you'd need to ask a Microsoft developer why they chose to seal that class. However, the architectural guidance literature I've been reading lately tends to favor an approach of "seal unless you know it will need to be extended." This literature tends to espouse using extension methods where possible. (I'm not saying I agree with it; I'm just saying that's what I've been reading lately.)

Even if the class weren't sealed, the properties in question might have been left not virtual, which would still leave you up the creek here.

In your specific scenario, I'd go with extension methods with your own unique names. It's about all you can do.

查看更多
迷人小祖宗
3楼-- · 2019-01-18 23:00

I would suggest that there is no good reason for sealing classes other than to protect the ignorant -err, I mean innocent. You know the old saying, "given them enough rope and they will hang themselves". Let them sway I say. Perhaps this is my C++ background, but I am quite comfortable knowing that I have the power to completely stuff things up if I am not diligent.

I tend to program by interface. The interfaces are of course public and any one is free to provide their own implementation that adheres to the contract expressed by the interface. My concrete classes that implement these interfaces tend to be a private concern and are marked internal and/or private. I don't feel that I need to seal such classes.

Where code reuse is desirable, I avoid reuse through inheritance, favouring composition and other techniques.

Sealing may also be valid on types that are considered plain-old-data types, but I'm not convinced wither way on this.

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-01-18 23:00

One of the practical uses where i have found sealed keyword useful is to avoid "Fragile class issues". Here's a video which shows one of the fragile base class issues http://www.youtube.com/watch?v=xnA3RUJcyY4

Let me explain a bit in detail.

Consider the below scenario where we have a parent class called as “DbParent” with a virtual method “Insert”.

class DbParent {

    public virtual void Insert()
    {
        Console.WriteLine("Parent insert");
    }

}

Below is a simple child class with his own “Insert” implementation which is installed across various locations.

  class DbChildClass : DbParent
  {
  public void  Insert()
    {
        Console.WriteLine("Child inserts");
    }

}

Now let’s say after some months of deployment parent class developers without understanding the impact on child classes go and add a new method “Add”. This “Add” method calls the “Insert” method internally (below is the code snippet for the same).

  class DbParent
  {
  public  void Add() // Adds method with out consulting
  {
  this.Insert();
  }

  public virtual void Insert()
  {
        Console.WriteLine("Parent insert");
  }
  }

Now client programs who invoke the “Add” method by creating child class objects expect that the “Child” class “Insert” implementation should be called.

  DbChildClass o = new DbChildClass();
  o.Add();
  Console.Read();

But whoaaaa, if you run the below code you will see the parent class “Insert” is called which is not EXPECTED.

So i would go and mark the class as "Sealed" to avoid such issues.

查看更多
smile是对你的礼貌
5楼-- · 2019-01-18 23:01

Just because something is an object, it doesn't mean it always should be wide open for everybody to extend or redefine it's behavior.

A good analogy would be a door and a lock. A door's nature is to let people to pass through it, that's what it's built for. Yet, most doors are designed with locks that can limit the ability of people to pass through them. The decision whether a door has a lock and whether that lock is locked by default is left to the architect of the room, based on what's in the room and who should have access to it, not on the fact that it's a door.

Of course, it can be frustrating if most of the doors in particular building are locked by default, especially if there's one you really want to go through. :-) I've been there myself and I've asked the same question. The short answer is that sometimes when designing a complex framework, people tend to err a little bit on the more cautios side and have classes sealed by default, unless there is explicit scenario that requires them to be extended.

查看更多
太酷不给撩
6楼-- · 2019-01-18 23:02

The short answer is, because Microsoft said so. The longer answer is that Microsoft has provided a mechanism to extend sealed classes, called extension methods.

In general, it's a bad idea to extend classes which which you don't have source code to. For example, you don't know what calling base method does to the internal data of the object. Yes, you can use reflector or whatever to figure it out, but in general it's much better to use composition or extension methods.

You also have to consider what inheritence actually is. It's not just a way to alter the class, it also provides polymorphism. What if you change the semantics of, say, the string class, then you pass your new string class to an object that expects a string to act in a specific way? sealed essentially enforces the contract that this object will always work the way you expect it to.

查看更多
Animai°情兽
7楼-- · 2019-01-18 23:08

Designing classes (or frameworks) to be extensible isn't trivial, and put simply inheritance is not the single principle of Object Oriented programming.

So sealed exists to allow the developer / designer to express and preserve those intentions. Sealing a class can also make their life easier by reducing the maintenance burden. It allows the original developer to control how the class (or framework) is extended, so they can make internal changes without worrying about breaking changes to others code.

One principle is that developers should seal any leaf classes by default. Then, when the developer creates an unsealed class intentionally, it forces them to think about extensibility.


Ref: Eric Lippert - Why Are So Many Of The Framework Classes Sealed?

查看更多
登录 后发表回答