|
Chapter 28 "A Disposable Class"In this brief chapter I present an abstract class Disposable that simplifies the implementation of the IDisposable interface. The IDisposable interface is normally implemented using the following idiom: class Program : IDisposable
{
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); // remove this from gc finalizer list
Console.WriteLine("Dispose called.");
}
// call Dispose(true) from Dispose, call Dispose(false) from finalizer
// dispose once only
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing) // called from Dispose
{
// Dispose managed resources.
}
// Clean up unmanaged resources here.
}
disposed = true;
}
~Program() // maps to finalize
{
Dispose(false);
}
}
Personally I find the Dispose(bool disposing) idiom confusing which means error prone. I got tired of copying and pasting this idiom into classes that implement IDisposable so I wrote an abstract class Disposable: // I got tired of copy and pasting IDisposable
public abstract class Disposable : IDisposable
{
protected bool disposed= false; // subclass needs to implement these two methods
abstract protected void DisposeManagedResources();
abstract protected void DisposeUnmanagedResources(); public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing) // called from Dispose
{
DisposeManagedResources();
}
DisposeUnmanagedResources();
}
disposed = true;
}
~Disposable() // maps to finalize
{
Dispose(false);
}
}
To use this class just inherit and implement the two abstract methods: abstract protected void DisposeManagedResources();
abstract protected void DisposeUnmanagedResources();
Here is a class that extends from Disposable: // class that wraps unmanaged resource
class Wrapper : Disposable, IMyUnmanagedWrapper
{
protected override void DisposeManagedResources()
{
//Console.WriteLine("Disposed Managed Resources.");
}
protected override void DisposeUnmanagedResources()
{
Console.WriteLine("Disposed Unmanaged Resources.");
}
public void Draw() {
if (disposed) { throw new ObjectDisposedException("Wrapper"); }
// mimic some type of unmanaged action
Console.WriteLine("Draw.");
}
}
Have fun! |
Send mail to
jeff_louie@yahoo.com with questions or
comments about this web site.
Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007 ©
|