About IDisposable.Dispose()

W

Water Cooler v2

I heard from someone that we must not implement IDisposable for all
classes. Can someone please tell me:

1. the reason why we must not implement IDisposable for all the classes
we write.
2. what is the correct way of implementing IDisposable.Dispose?
3. what is the preferred way, if there is one over the other, of
calling the Dispose method on an object that implements IDisposable. Is
it the way that uses the "using(object){}" construct or the way that
emphasises on explicitly calling the Dispose method on the object?
 
M

Marc Gravell

1: a better question would be "why should we implement dispose on an
object"? The answer is generally to (either):
* release an unmanaged resource in a deterministic fashion
* release any disposable managed objects that we own in a class
A Dispose method (nor a finalizer) is not the same as a C++ style
destructor; it is not really intended as a place to explicitely release
managed resources that you own - leave that to the GC.

2: erm, by providing a Dispose() method? If the class has a finalizer
(generally *only* for unmanaged wrappers), then this is common:

class SomeClass() : IDisposable {
public void Dispose() { Dispose(true); }
~SomeClass() { Dispose(false); }
protected virtual Dispose(bool disposing) {
if(disposing) {
// only release *managed* resources if disosing
// (else GC may have eaten them already)
}
// release unmanaged resources
}
}

Note that for best use it should be safe to Dispose() an object
multiple times - e.g. in Dipose() ceck if things are null (objects) / 0
(handles); if not, clean them then wipe the field so it doesn't get
re-applied if Dispose()d again.

3: "using". It evaluates to the same thing, but you are less likely to
get it wrong. And it saves time.

Marc
 
B

Brian Gideon

Water said:
I heard from someone that we must not implement IDisposable for all
classes. Can someone please tell me:

1. the reason why we must not implement IDisposable for all the classes
we write.

It's the same reason you don't implement IEnumerator, IAsyncResult,
etc. If it's not needed don't bother. Here are few general guidelines
that may help determine if it's needed.

* DO implement IDisposable if your class directly uses unmanaged
resources. For example, a handle obtained from the Win32 API, etc.

* DO implement IDisposable if your class indirectly uses unmanaged
resources. For example, if your class has a reference to another
object that implements IDisposable.

* DO override the Finalize method if your class directly uses unmanaged

resources.

* DON'T override the Finalize method if your class does not directly
use managed resource. In other words, don't override Finalize just
because your class has a reference to another class that implements
IDisposable.

* DON'T override the Finalize method in a class who's base class
already overrides Finalize. In other words, if the base class provides
the protected Dispose(disposing as Boolean) method then you don't need
to override Finalize.

* DON'T implement IDisposable if your class does not hold unmanaged
resources either directly or indirectly. For clarity, I don't consider
objects whose scope is limited to methods as being held by the class
itself. If a method in your class uses an IDisposable object locally
then just make sure it's Dispose method is called before the method
ends.
2. what is the correct way of implementing IDisposable.Dispose?

See the MSDN documentation.

http://msdn2.microsoft.com/en-us/library/fs2xkftw.aspx

Also, consider using the SafeHandle class.
3. what is the preferred way, if there is one over the other, of
calling the Dispose method on an object that implements IDisposable. Is
it the way that uses the "using(object){}" construct or the way that
emphasises on explicitly calling the Dispose method on the object?

Well, I can tell you that I prefer to use the 'using' keyword, but
sometimes it just makes more sense to call Dispose explicitly.
 
D

Dave Sexton

Hi,

I'd just like to add that you can get the standardized disposal logic for your classes by deriving from
System.ComponentModel.Component, which has the added benefit that your class can be added to designers at design-time, if desired,
from the VS.NET toolbox.

Another reason one would implement IDisposable on a class is to manage the lifetime of an instance. e.g. TransactionScope. This
has the added benefit of supporting the C# "using" statement:

using (TransactionScope scope = new TransactionScope())
{
// TODO: something transacted
}

There are classes in the framework that implement IDisposable explicitly and provide a different method such as "Close" instead of
"Dispose". Just semantics, but you will see it from time to time. The functionality of these classes is still, commonly, the
standardized disposal logic that the other respondents mentioned.
 
U

uladzimir

Great reply and I just want to add that Water Cooler v2 should try to
avoid using finalizers (i.e. ~T()). The class that contains a
finalization code should be as small as possible, just wrapper that
incapsulate these resources.

If a class implements Finalizer, you have to implement IDisposable to
give your user a possibility to explicitly clean up the resources.

Vladimir.
_____________________________
http://cogitosoft.blogspot.com/
http://landvp.com/
 
B

Brian Gideon

Vladimir,

That's an excellent point that I didn't articulate as well as I should
have. Implementing IDisposable does not imply that you should override
Finalize. But, the converse is true.

Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top