Rajesh Reddy G
Rajesh Reddy G

Reputation: 21

What is the reason behind sealing data provider classes (like SqlConnection, SqlCommand etc.,) in ADO.NET?

Why can't we inherit from the data provider classes (like SqlConnection, SqlCommand) in ADO.NET?

Is there any reason behind that?

Upvotes: 1

Views: 396

Answers (1)

Maxim Gershkovich
Maxim Gershkovich

Reputation: 47189

I am reposting the content from the link in answer that @Damien_The_Unbeliever provided encase it ever goes down especially given that it is written by Eric Lippert.

Why Are So Many Of The Framework Classes Sealed?
22/01/2004 3 minutes to read

I talked earlier this month about some issues in subclassing,
and recommended sealing your classes. A Joel On Software reader asks
why Microsoft ships so many sealed classes in the framework. The
poster said: "I've yet to see a reasonable explanation about why they
limited flexibility in such a way. "

Well, every public class that my team produces is sealed if possible.
If it is not possible to seal a class then, if possible, it has an
inheritance demand on it so that only someone with the MSFT private
key can subclass it. My reasons for insisting upon this policy boil
down to one overriding principle:

Good code does exactly what it was designed to do, no more, no less.

Let me expand upon that in four ways.

  1. Philosophical. OOP design includes subclassing to represent the
    polymorphic "is a" relationship between two things. A Giraffe IS AN
    Ungulate IS A Mammal IS AN Animal... Unless I can think of a clear
    case where a customer would need to express an IS A relationship with
    some code that I produce, I don't allow for such cases.

  2. Practical. Designing classes so that they can be effectively
    extended by third parties is HARD. (Look at the collection base
    classes for example.) You have to get the design right -- what is
    protected? You have to implement that design correctly. The test
    matrix grows enormously because you have to think about what weird
    things people are going to do. You have to document the protected
    methods and write documentation on how to properly subclass the thing.

This is all expensive and time consuming -- that is time that we could
be spending looking for bugs in more important user scenarios,
planning future versions, fixing security holes, whatever. There is
only a finite amount of developer time we can spend on designing and
implementing code, so we have to spend it the way that benefits
customers most. If the class is not designed to be extended, I'm going
to avoid all that expense by sealing it. I am not going to release
half-baked classes that look extensible but in fact are not quite
there.

  1. Compatible. If in the future I discover that I should have sealed a
    class, I'm stuck. Sealing a class is a breaking change. If I discover
    that I should have left a class unsealed, unsealing in a future
    version is a non-breaking change. Sealing classes helps maintain
    compatibility.

  2. Secure. the whole point of polymorphism is that you can pass around
    objects that look like Animals but are in fact Giraffes. There are
    potential security issues here.

Every time you implement a method which takes an instance of an
unsealed type, you MUST write that method to be robust in the face of
potentially hostile instances of that type. You cannot rely upon any
invariants which you know to be true of YOUR implementations, because
some hostile web page might subclass your implementation, override the
virtual methods to do stuff that messes up your logic, and passes it
in. Every time I seal a class, I can write methods that use that class
with the confidence that I know what that class does.

Now, I recognize that developers are highly practical people who just
want to get stuff done. Being able to extend any class is convenient,
sure. Typical developers say "IS-A-SHMIZ-A, I just want to slap a
Confusticator into the Froboznicator class". That developer could
write up a hash table to map one to the other, but then you have to
worry about when to remove the items, etc, etc, etc -- it's not rocket
science, but it is work.

Obviously there is a tradeoff here. The tradeoff is between letting
developers save a little time by allowing them to treat any old object
as a property bag on the one hand, and developing a well-designed,
OOPtacular, fully-featured, robust, secure, predictable, testable
framework in a reasonable amount of time -- and I'm going to lean
heavily towards the latter. Because you know what? Those same
developers are going to complain bitterly if the framework we give
them slows them down because it is half-baked, brittle, insecure, and
not fully tested!

Upvotes: 2

Related Questions