S. Larws
S. Larws

Reputation: 373

What is the reason for the structure of Microsoft's dispose pattern?

The suggested dispose pattern from Microsoft says that Dispose() and finalizer should both call a virtual third method Dispose(bool). So it looks something like this:

public class DisposeBase : IDisposable
{
    private bool _Disposed = false;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~DisposeBase()
    {
        Dispose(false);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_Disposed)
        {
            if (disposing)
            {
                /* Get rid of managed resources */
            }

            /* Get rid of unmanaged resources */

            _Disposed = true;
        }
    }
}

Derived classes would override Dispose(bool). I thought about restructuring it a bit like this:

public abstract class ExtendableResourceHandlerBase : IDisposable
{
    private bool _Disposed = false;

    /* private resources managed and unmanaged */

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~DisposeBase()
    {
        Dispose(false);
    }

    private void Dispose(bool disposing)
    {
        if (!_Disposed)
        {
            if (disposing)
            {
                ManagedDispose();

                // Dispose of own managed resources
            }

            UnmanagedDispose();

            // Dispose of own unmanged resources

            _Disposed = true;
        }
    }

    protected abstract void ManagedDispose();

    protected abstract void UnmanagedDispose();

    protected abstract xxx ExtendMe(....)

    // other member functionality
}

I am thinking of scenario where in a framework you are declaring an abstract base class that provides an interface and some implementation aquiring resources that need to be disposed - hence the IDisposable interface. Now clients extending this base class would be forced to think about the disposal of their managed and unmanaged resources as well. In the case of the suggested pattern from microsoft one might forget about it. Please think of the name ExtendableResourceHandlerBase as just a place holder.

In my opinion this would make it easier for clients deriving from DisposeBase to implement their dispose methods. And as answers of another question show, other people think so too. The only reason I can think of why the good folks at microsoft build their pattern as it is now, is not to split up the disposal of managed and unmanaged resources. Are there any other reasons for it? Thanks alot for enlightening me.

Upvotes: 2

Views: 405

Answers (1)

supercat
supercat

Reputation: 81267

When Microsoft documented and recommended the Dispose pattern, it was expected that classes which implemented IDisposable would often have one set of resources they would clean up in Dispose and a smaller set they clean up in Finalize; the pattern was designed around that expectation. In practice, the only classes which should ever override Finalize for any purpose other than to log failures to call Dispose are those which inherit directly from Object. If a derived class whose parent doesn't override Finalize would use an unmanaged resource that should be cleaned up in a finalizer, it shouldn't override Finalize itself nor hold the unmanaged resource directly, but instead encapsulate the resource in an instance of a class dedicated to that purpose. This will help avoid a lot of weird and tricky edge cases that can otherwise arise with finalization of objects which hold a mixture of managed and unmanaged resources.

Having the interface method which simply chains to a virtual method is a good idea, even if the protected void Dispose(bool) method will never get called with its parameter being anything other than true. The pattern might be a little cleaner if the protected virtual method were differentiated by name rather than by a useless parameter, but enough people expect the Microsoft pattern that one may as well use it even if it's not perfect.

Upvotes: 5

Related Questions