Search code examples
c#.netdesign-patternsdryidisposable

Template method pattern with IDisposable in C#


I see that the common guideline to implement the disposable pattern in C# is to have an abstract base class that implements the Dispose() method from IDisposable interface and provides a protected virtual Disposable(bool) method. Then sub-classes need to override Disposable(bool) and always do something like:

if (!disposed && disposing)
{
    // dispose resources here

    disposed = true;
}

My question is: wouldn't be possible to reuse this pattern? I don't like to have to manage this "disposed state" in every subclass. We could have some abstract base class like this:

public abstract class AbstractResource : IDisposable
{
    private bool myDisposed = false;

    protected abstract void ReleaseUnmanagedResources();

    protected virtual void ReleaseManagedResources()
    {
        // optionally override this to explicitly call Dispose() of other IDisposable objects
    }

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

    private void Dispose(bool disposing)
    {
        if (!myDisposed)
        {
            if (disposing)
            {
                ReleaseManagedResources();
            }

            ReleaseUnmanagedResources();

            myDisposed = true;
        }
    }

    ~AbstractResource()
    {
        Dispose(false);
    }
}

Then users of this class only need to implement ReleaseUnmanagedResources and (optionally) ReleaseManagedResources. No need to deal with booleans.

I've found that this article proposes a similar technique. But that is it! Nobody else mentions it. Are there flaws with this approach?


Solution

  • The biggest flaw with this method is that it takes away a finite resource... the ability to derive from exactly one class means if I use your implementation, I basically can kiss OOP goodbye because I will need to derive many classes from your class and cannot derive them from another class as I could if I implemented the interface.

    So in the real world, you'd have a wild mix of some classes using your baseclass, some rolling their own baseclass for business purposes that already incorporates IDisposable and some just implementing the interface. I cannot speak for everybody, but I'd rather have the same construct applied to all classes using a tool (R# for example) than having a wild mixture of things.

    If we had the ability to derive from more than one base class, it might be a thing, but we don't in C#.