When would I implement IDispose on a class as opposed to a destructor? I read this article, but I'm still missing the point.
My assumption is that if I implement IDispose on an object, I can explicitly 'destruct' it as opposed to waiting for the garbage collector to do it. Is this correct?
Does that mean I should always explicitly call Dispose on an object? What are some common examples of this?
The only thing that should be in a C# destructor is this line:
That's it. Nothing else should ever be in that method.
There is a very good description on MSDN:
It's pretty simple really. I know it's been answered but I'll try again but will try to keep it as simple as possible.
A destructor should generally never be used. It is only run .net wants it to run. It will only run after a garbage collectoin cycle. It may never actually be run during the lifecycle of your application. For this reason, you should not ever put any code in a destructor that 'must' be run. You also can't rely on any existing objects within the class to exist when it runs (they may have already been cleaned up as the order in which destructors run in is not garanteed).
IDisposible should be used whenever you have an object that creates resources that need cleaning up (ie, file and graphics handles). In fact, many argue that anything you put in a destructor should be putin IDisposable due to the reasons listed above.
Most classes will call dispose when the finalizer is executed but this is simply there as a safe guard and should never be relied upon. You should explicitly dispose anything that implements IDisposable when you're done with it. If you do implement IDisposable, you should call dispose in finalizer. See http://msdn.microsoft.com/en-us/library/system.idisposable.aspx for an example.
Here is another fine article which clears up some of the mist surrounding IDisposable, the GC and dispose.
Chris Lyons WebLog Demystifying Dispose
A finalizer (aka destructor) is part of garbage collection (GC) - it is indeterminate when (or even if) this happens, as GC mainly happens as a result of memory pressure (i.e. need more space). Finalizers are usually only used for cleaning up unmanaged resources, since managed resources will have their own collection/disposal.
Hence
IDisposable
is used to deterministically clean up objects, i.e. now. It doesn't collect the object's memory (that still belongs to GC) - but is used for example to close files, database connections, etc.There are lots of previous topics on this:
Finally, note that it is not uncommon for an
IDisposable
object to also have a finalizer; in this case,Dispose()
usually callsGC.SuppressFinalize(this)
, meaning that GC doesn't run the finalizer - it simply throws the memory away (much cheaper). The finalizer still runs if you forget toDispose()
the object.The role of the
Finalize()
method is to ensure that a .NET object can clean up unmanaged resources when garbage collected. However, objects such as database connections or file handlers should be released as soon as possible, instead on relying on garbage collection. For that you should implementIDisposable
interface, and release your resources in theDispose()
method.