« Home | Media Center Update » | Class Designer C++ Support Cut » | Blog Marketing » | Indigo » | MPAA » | .NET Array Expectations » | Wrestling Gold from Today's Software Projects » | MCE 2005 » | RSS Audio Convenience » | doxygen »

DisposableResource

This post contains some very minor variations of the Dispose pattern implemented in a class that implements IDisposable. A typical example of how to implement the Dispose idiom can be found over here. The DisposableResource implementation shown below separates out disposal of managed resources from the disposal of unmanaged resources. The derived class implementor then just has to override either DisposeOfManagedResources or DisposeOfUnmanagedResources or both depending on their resource management requirements. I know its a minor thing, but it just saves having the if-then logic contained in the Dispose( bool ) method being duplicated all over the place. There’s also a couple of convenience methods. The ThrowIfDisposed method can be called whenever you want to ensure this object has not been disposed of. The DisposeOf method does a null check and then disposes of the supplied object if it can. This saves some typing and improves clarity in disposal method overrides.


/// <summary>
/// A base class that provides resource-management functionality for
/// derived classes. Derived classes should override the <see cref="DisposeOfManagedResources"/>
/// and/or the <see cref="DisposeOfUnmanagedResources"/> methods. Default implementations
/// of both these methods are provided so that derived classes only require
/// specializations that apply to derived class resource management requirements.
/// </summary>
public class DisposableResource : IDisposable
{
private bool hasBeenDisposed;

/// <summary>
/// Initializes a <see cref="DisposableResource"/> instance.
/// </summary>
public DisposableResource()
{
}

/// <summary>
/// The finalizer for a <see cref="DisposableResource"/> frees the
/// unmanaged resources but not the managed resources.
/// </summary>
~DisposableResource()
{
Dispose( false );
}

/// <summary>
/// Disposes of this object. Both managed and unmanaged resources are freed.
/// </summary>
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}

/// <summary>
/// Throws an <see cref="ObjectDisposedException"/> if this object has already
/// been disposed. This method can be used to check the validity of object
/// usage.
/// </summary>
protected void ThrowIfDisposed()
{
if ( hasBeenDisposed )
throw new ObjectDisposedException(
"This object has already been disposed: " + ToString() );
}

/// <summary>
/// Disposes of the supplied object if the parameter value is not null.
/// </summary>
/// <param name="disposable">The object to be disposed.</param>
protected void DisposeOf( IDisposable disposable )
{
if ( disposable != null )
disposable.Dispose();
}

/// <summary>
/// Frees resources within this object. This is separated into freeing
/// managed and unmanaged resources. Managed resources are only freed
/// if requested. Unmanaged resources are always freed.
/// </summary>
/// <param name="freeManagedResources">
/// Whether managed resources are to be freed.
/// </param>
private void Dispose( bool freeManagedResources )
{
if ( hasBeenDisposed ) return;

if ( freeManagedResources )
DisposeOfManagedResources();

DisposeOfUnmanagedResources();

hasBeenDisposed = true;
}

/// <summary>
/// Frees all managed resources held by this object e.g. unhooking events,
/// disposing of all IDisposable members etc. Derived classes should call
/// base.ManagedDispose() as part of their implementation.
/// </summary>
protected virtual void DisposeOfManagedResources()
{
}

/// <summary>
/// Frees all unmanaged resources resources held by this object.
/// Derived classes should call base.FreeUnmanagedResources() as part of the
/// implementation.
/// </summary>
protected virtual void DisposeOfUnmanagedResources()
{
}
}

Links to this post

Create a Link