views:

482

answers:

3

Here is code from MSDN. I don't understand why the work isn't just done in the regular Dispose() method here. What is the purpose of having the Dispose(bool) method? Who would ever call Dispose(false) here?

public void Dispose() 
{
    Dispose(true);

    // Use SupressFinalize in case a subclass
    // of this type implements a finalizer.
    GC.SuppressFinalize(this);      
}

protected virtual void Dispose(bool disposing)
{
    // If you need thread safety, use a lock around these 
    // operations, as well as in your methods that use the resource.
    if (!_disposed)
    {
        if (disposing) {
            if (_resource != null)
                _resource.Dispose();
                Console.WriteLine("Object disposed.");
        }

        // Indicate that the instance has been disposed.
        _resource = null;
        _disposed = true;   
    }
}
+7  A: 

The finalizer would call Dispose(false) - in which case you don't touch any of the other managed resources (which may already have been finalized).

Personally I don't follow this pattern often - because I only very, very rarely need a finalizer, and it's also rare for me to write a non-sealed IDisposable implementation. If you're writing a sealed class without a finalizer, I would go for a simple implementation.

Jon Skeet
You should still follow this pattern if you're encapsulating an IDisposable resource in a non-sealed class, though, so subclasses can be handled properly (and consistently).
Reed Copsey
Even if no finalizer is needed.
Reed Copsey
@Reed: The only reason for doing this when subclasses are involved is so that *they* can have finalizers - otherwise why bother with a parameter which will always be true?
Jon Skeet
+1 on the 'I don't follow this pattern', it's useful if you have a Win32 handle or the like, but otherwise needless as you shouldn't have a finalizer.
csharptest.net
@Jon: True, except that, to provide a virtual Dispose() method to your subclasses, you would need to change the name (since you can't have a protected virtual Dispose and Dispose, unless you implement Dispose explicitly) - but in any case, it's going to be a non-standard implementation that your subclass will deal with. Why not provide them exactly what's expected?
Reed Copsey
@Reed: What's wrong with just a public virtual Dispose() method?
Jon Skeet
Another +1 for "don't follow this pattern" (not that Jon needs it). The MSDN docs do a poor job of explaining that all this extra stuff is only needed in "corner" cases. 1) most classes don't manage native resources, and 2) make your classes sealed (inheritance is over used).
Dan
+3  A: 

This is to allow the finalizer to work property, as well as to allow subclasses which derive from your class to dispose properly.

If you want more detailed info, I wrote a 5 part blog series on IDisposable, and covered the subclassing issue in detail in the Subclass from an IDisposable Class article.

Reed Copsey
A: 

Your Dispose(disposing) method shouldn't explicitly free resources if it is called from finalizer, since these resources can be already freed by GC.

So, Dispose(disposing) should check whether it was called manually or from GC and acts appopriately.

elder_george