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?
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#.