patterncsharpModerate
DisposableObject base class for C#
Viewed 0 times
disposableobjectclassforbase
Problem
I commonly run into the need to implement IDisposable in my code. To correctly dispose of both managed and unmanaged resources requires a reasonable amount of boilerplate code. Based on the documentation found here I have created the following base class.
My intent is that any object I create that needs to dispose of resources doesn't need to rewrite the boilerplate code. Rather it can inherit from this object and implement two abstract methods.
Does this appear correct? And has anyone else written something similar? I would appreciate comments on the style, correctness and how well this conforms to best practices.
EDIT: Final Implementation
```
public abstract class DisposableObject : IDisposable
{
public bool Disposed { get; private set;}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~DisposableObject()
{
Debug.Assert(Disposed, "WARNING: Object finalized without being disposed!");
Dispose(false);
}
private void Dispose(bool disposing)
{
if (!Disposed)
{
if (disposing)
{
DisposeManagedResources();
}
DisposeUnmanagedResources();
Disposed = true;
}
}
protect
My intent is that any object I create that needs to dispose of resources doesn't need to rewrite the boilerplate code. Rather it can inherit from this object and implement two abstract methods.
Does this appear correct? And has anyone else written something similar? I would appreciate comments on the style, correctness and how well this conforms to best practices.
public abstract class DisposableObject : IDisposable
{
private bool _disposed = false;
public bool Disposed
{
get { return _disposed; }
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~DisposableObject()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
DisposeManagedResources();
}
DisposeUnmanagedResources();
_disposed = true;
}
}
protected abstract void DisposeManagedResources();
protected abstract void DisposeUnmanagedResources();
}EDIT: Final Implementation
```
public abstract class DisposableObject : IDisposable
{
public bool Disposed { get; private set;}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~DisposableObject()
{
Debug.Assert(Disposed, "WARNING: Object finalized without being disposed!");
Dispose(false);
}
private void Dispose(bool disposing)
{
if (!Disposed)
{
if (disposing)
{
DisposeManagedResources();
}
DisposeUnmanagedResources();
Disposed = true;
}
}
protect
Solution
I would think on making two changes:
- Make one or both
Dispose*Resourcesmethods virtual instead of abstract. Though it highly depends on how often do you need to handle unmanaged resources. I can't remember last time I was handling them and I would hate overriding this method in each class just to make it empty.
- I would add some logging either to your finalizer method or to
Dispose(bool disposing)method in order to catch situations when disposable object wasn't disposed correctly by callingDispose()method. Most developers are looking for such information and you have a good place to inject it.
Context
StackExchange Code Review Q#2720, answer score: 16
Revisions (0)
No revisions yet.