Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / December 2005

Tip: Looking for answers? Try searching our database.

Interface Inheritance for IDisposable

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Grafix - 05 Dec 2005 20:36 GMT
All -
This might be a purist question, but i want to convince my handler with a
reasonable argument.

Lets say i have an object *internal* to my assembly (InternalMyObject) and
it implements an exposed interface (IMyObject). I want to specify that the
object that implements IMyObject is a disposable object, so i derive
IMyObject from IDisposable.
interface IMyObject : IDisposable {}

It is easy to say now
 IMyObject obj = SomehowCreate();
 obj.Dispose();

If i *dont* inherit IMyObject from IDisposable, i must say
if(obj is IDisposable)
  ((IDisposable)obj).Dispose();

which sort of looks clumsy.
The argument *against* the first approach is that, inheritance specifies a
"IS A" relation-ship and my handler argues that IMyObject "IS NOT A"
IDisposable.

He says that it should be the concrete-object that shoudl implement
IDisposable, and we shoudl always query for IDisposable(C# 'is') -  but from
a pragmatic perspective i feel the first approach is better.

Whats the preferred way of saying that the interface an (internal) object
points to is disposable? Should the interface derive from IDisposable or the
client should do a QI for the same?

Thanks for ur time.

Regardz
Grafix.

Joerg Jooss - 05 Dec 2005 21:45 GMT
> All -
>  This might be a purist question, but i want to convince my handler
[quoted text clipped - 26 lines]
> object points to is disposable? Should the interface derive from
> IDisposable or the client should do a QI for the same?

My take: Let the class implement it, and if your classes share an
inheritance tree, let a base class implement IDisposable according to
the usual pattern. Derived classes may then override void Dispose(bool)
if required.

Cheers,
Signature

http://www.joergjooss.de
mailto:news-reply@joergjooss.de

Jon Shemitz - 05 Dec 2005 22:30 GMT
>  Lets say i have an object *internal* to my assembly (InternalMyObject) and

The design issues aren't really affected by internal vs public: The
same principle distinguish good design from bad design. A bad design
will mislead someone maintaining your internal code in just the same
way as a bad design will mislead someone consuming your public API.

> it implements an exposed interface (IMyObject). I want to specify that the
> object that implements IMyObject is a disposable object, so i derive
> IMyObject from IDisposable.
>  interface IMyObject : IDisposable {}

The thing is, people expect an interface to represent behavior, not
accidents of implementation. By deriving IMyObject from IDisposable,
you are not telling people that every implementation of IMyObject will
have state data that needs to be disposed of, but that IMyObject
represents state data that needs to be disposed of. The difference is
subtle but real, and breaking the patterns can waste people's time,
downstream.

> If i *dont* inherit IMyObject from IDisposable, i must say
>  if(obj is IDisposable)
>    ((IDisposable)obj).Dispose();

Fwiw, the idiom

 IDisposable Disposable = obj as IDisposable;
 if (Disposable != null)
   Disposable.Dispose();

is smaller (at the object code level) and faster.

> The argument *against* the first approach is that, inheritance specifies a
> "IS A" relation-ship and my handler argues that IMyObject "IS NOT A"
> IDisposable.

He's right.

> He says that it should be the concrete-object that shoudl implement
> IDisposable, and we shoudl always query for IDisposable(C# 'is') -  but from
> a pragmatic perspective i feel the first approach is better.

OK, let's be pragmatic. Your way saves a little time when you code it
the first time, by letting you avoid an `as` cast and an `if != null`
test - but your way also wastes a little time whenever anyone reads
your code. They'll ask "Where does this Dispose() call come from?"
Often they'll F12 to the definition of IMyObject to see what's going
on. By contrast, anyone reading an as/if pair will know exactly what's
going on.

Bottom line: keeping your code semantically clean saves money over the
life of the code.


Signature

    <http://www.midnightbeach.com>

David Browne - 06 Dec 2005 01:51 GMT
>>  Lets say i have an object *internal* to my assembly (InternalMyObject)
>> and
[quoted text clipped - 36 lines]
>
> He's right.

I have to disagree.  Interface inheratence does not define an "IS A"
relationship, but rather an "OPERATES LIKE" relationship.  Inheriting from
IDisposable simply indecates that implementing classes will likely have a
Create, Use, Cleanup lifecycle.

But more importantly, he's missing the most important thing about disposable
types.  With any disposable type the first-order concern is making sure that
client code actually disposes the instances!

If you are difining an interface it is likely that conusmer code will not
know about the actual implementation.  So if you hide the fact that the type
is disposable in the concrete implementation then you increase the
possibility that client code will use the type without disposing it.  if
IMyObject doesn't inherit from IDisposable then this code:

void DoSomething()
{
 IMyObject myObj = MyObjectFactory.GetMyObject();
 myObj.Flarg();
}

is wrong, but not obviously wrong. No static analysis of the code can reveal
that a Disposable object is being used without being Disposed.  A developer
who wrote the above, incorrect code, would rightly ask,
"Well how the hell was I supposed to know that IMyObject was disposable?".
The only way would by to put that stupid little "is IDisposable" test on
absulutely every use of an object through an interface or non-sealed type
variable on the off chance that the concrete run-time type is disposable.

David
Lasse Vågsæther Karlsen - 06 Dec 2005 09:05 GMT
I think in the OP's case he can do pretty much what he wants to since
it's his object and his interface and judging by the names in his
example there is a 1-to-1 match. Probably he has made the interface so
that he can use the full range of methods on the class internally in the
assembly and yet expose a set of those methods to other assemblies
through an interface.

In this case he can just as well specify that his interface also brings
IDisposable into the game since it's his object.

On a general basis, unless the interface contract (documentation) states
that there is resources that needs to be disposed of in every
implementation of that interface, I would not do it and instead document it.

<snip>

> I have to disagree.  Interface inheratence does not define an "IS A"
> relationship, but rather an "OPERATES LIKE" relationship.  Inheriting from
> IDisposable simply indecates that implementing classes will likely have a
> Create, Use, Cleanup lifecycle.

Implementing classes *will have* a cleanup method, but it can of course
be empty.

> But more importantly, he's missing the most important thing about disposable
> types.  With any disposable type the first-order concern is making sure that
> client code actually disposes the instances!

And you won't get the compiler to enforce that no matter what you do.
The closest thing you'll get is to provide a finalizer that throws an
exception because it obviously should never be executed.

> If you are difining an interface it is likely that conusmer code will not
> know about the actual implementation.  So if you hide the fact that the type
> is disposable in the concrete implementation then you increase the
> possibility that client code will use the type without disposing it.  if
> IMyObject doesn't inherit from IDisposable then this code:

There could be many gotchas with an object that you don't know of. There
is no way you will be able to talk the compiler into enforcing all of
these. The only good way to make sure the object is used correctly is to
provide a good set of documentation for it.

> void DoSomething()
> {
[quoted text clipped - 6 lines]
> who wrote the above, incorrect code, would rightly ask,
> "Well how the hell was I supposed to know that IMyObject was disposable?".

He should've read the documentation. Not everything can be inferred from
reading method names and class signatures.

> The only way would by to put that stupid little "is IDisposable" test on
> absulutely every use of an object through an interface or non-sealed type
> variable on the off chance that the concrete run-time type is disposable.

If you're going to be paranoid about IDisposable, then yes. There's also
such a thing as future-proof. What if you use a class in your current
project and it doesn't implement IDisposable, and tomorrow you upgrade
to the latest version. The compiler won't tell you that you're now
supposed to dispose of the object but you have introduced a problem anyway.

Would I write code to make sure every such use would be future-proof? No.

Signature

Lasse Vågsæther Karlsen
http://usinglvkblog.blogspot.com/
mailto:lasse@vkarlsen.no
PGP KeyID: 0x2A42A1C2

Brian Gideon - 06 Dec 2005 14:45 GMT
Grafix,

There is no general rule regarding this.  It depends on your specific
situation.  If you want all IMyObject objects to behave like
IDisposable objects as well then IMyObject should implement
IDisposable.  It's really that simple.

Be careful about your usage of the word inherits.  There is a
distinction between inheriting and implementing despite C#'s syntax
being the same.  VB.NET actually uses two keywords to make the
distinction (Inherits and Implements).

If you want examples from the BCL where interfaces specify IDisposable
then take a look at IDbConnection, IDbCommand, IDbTransaction,
IResourceWriter, IContainer, IComponent, and IDesigner just to name a
few.

If you want examples where a QI is performed to test for IDisposable
then take a look at how the compiler expands the foreach construct.

My point is that Microsoft does it both ways.

Brian

> All -
>  This might be a purist question, but i want to convince my handler with a
[quoted text clipped - 31 lines]
> Regardz
> Grafix.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.