There is a lot of misinformation out there about IDisposable. It is a PATTERN that helps to accomplish what used to be traditionally accomplished via a destructor in C++. The problem is that in .NET, destruction of an object is not deterministic (it doesn't happen automatically when an object goes out of scope, but rather occurs at the time of Garbage Collection which is on a seperate low priority thread).
You do not need to implement Dispose unless you have a resource which needs to be released in some fashion. For instance, if any of your private data members implement Dispose, you should probably implement Dispose as well and call Dispose on those private members in your Dispose. Likewise, you should release any PInvoke handles in Dispose.
Also, the Dispose method is NOT called automatically for you upon garbage collection. This is the biggest piece of misinformation. You have to call Dispose from your Destructor (C#) or Finalize (VB.NET). Here is a good pattern for implementing Dispose:
public class Foo : IDisposable
{
public Foo()
{
// Allocate some resource here
}
~Foo()
{
Dispose( false );
}
public void Dispose()
{
Dispose( true );
}
private void Dispose( bool disposing )
{
// De-allocate resource here
if ( disposing )
GC.SuppressFinalize( this );
}
}
The reason that you call GC.SupressFinalize is that if your object has a finalizer, your object will actually get promoted to the next GC generation, because it has to call Finalize the first time the GC runs around, and can't release your object until finalization is finished, and therefore the memory is actually not released until the 2nd run through by the GC. If you call Dispose manually, then you can skip the finalizer, allowing your object to be released during the first pass of the GC.
To get the most benefit out of Dispose, use the using keword:
using ( Foo f = new Foo() )
{
// Do something with Foo
}
This is exactly the same as if you had written this:
Foo f;
try
{
f = new Foo();
// Do something with Foo
}
finally
{
f.Dispose();
}
Some people like to set a boolean in their class called _disposed, and then check that bool during every method call, and throw an exception if you attempt to call a method on an object after Dispose is called. For internal project classes, I generally consider this overkill, but might be a good thing to do if you are creating a library for consumption by 3rd parties.