What follows is a typical dispose pattern example:
public bool IsDisposed { get; private set; }
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (disposing)
{
//perform cleanup here
}
IsDisposed = true;
}
}
~MyObject()
{
Dispose(false);
}
I understand what dispose does, but what I don't understand is why you would want to call dispose(false) in the destructor? If you look at the definition it would do absolutely nothing, so why would anyone write code like this? Wouldn't it make sense to just not call dispose from the destructor at all?
There are no destructors in C#. That's a Finalizer, which is a different thing.
The distinction is whether you need to clean up managed objects or not. You don't want to try to clean them up in the finalizer, as they may themselves have been finalized.
I just recently happened to look at the Destructors page of the C# Programming Guide. It shows that I was mistaken in my answer, above. In particular, there is a difference between destructor and finalizer:
is equivalent to
Inside the if(disposing) you are supposed to call dispose/close on managed objects that have unmanaged resources (e.g. database connections).When the finalizer is called these objects are not longer reachable so the objects themselves can be finalized and you don't need to call dispose on them. Also the order of finalization is undeterminated so you may be calling dispose on already disposed objects.
There's much more info in the “Dispose, Finalization, and Resource Management Design Guidelines”.
Edit: link.
The finalizer is used as a fall-back if the object is not disposed properly for some reason. Normally the
Dispose()
method would be called which removes the finalizer hookup and turns the object into a regular managed object that the garbage collector easily can remove.Here is an example from MSDN of a class that has managed and unmanaged resources to clean up.
Notice that the managed resources are only cleaned up if
disposing
is true, but unmanaged resources is always cleaned up.The following example demonstrates how to create a resource class that implements the IDisposable interface: https://msdn.microsoft.com/en-us/library/System.IDisposable.aspx
In Dispose(bool disposing) function: If disposing equals true, the method has been called directly or indirectly by your code. Managed and unmanaged resources can be disposed. If disposing equals false, the method has been called by the runtime from inside the finalizer and you should not reference other objects. Only unmanaged resources can be disposed.
I think the confusion is due to the fact that in your example you aren't releasing any unmanaged resources. These also need to be released when dispose is called via garbage collection and they would be released outside the check for
disposing
. See the MSDN example relating to releasing unmanaged resources. The other that that would/should happen outside the check is a call to any base class Dispose method.From the quoted article: