IDisposable pattern is expensive to implement. I've counted 17 lines of code before even starting to actually dispose resources.
Eric Lippert recently wrote a blog post bringing up an interesting point: any time a finalizer runs, it is a bug. I think it make perfect sense. If the IDisposable pattern is always followed, Finalizer should always be suppressed. It will never have a chance to run. If we accept that finalizer run is a bug, then does it make sense to have a guideline to force developers to derive from the following abstract class and forbid directly implementing the IDisposable interface.
public abstract class AbstractDisaposableBase: IDisposable
{
~AbstractDisaposableBase()
{
ReportObjectLeak();
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected abstract void Dispose(bool disposing);
[Conditional("DEBUG")]
private void ReportObjectLeak()
{
//Debug.Assert(false, "leaked instance");
//throw new Exception("leaked instance");
}
}
The benefits are clear:
class MyClass1 : DisablableBase
{
protected override void Dispose(bool disposing)
{
//dispose both managed and unmamaged resources as though disposing==true
}
}
Not disposed object got reported
Disposable pattern is always followed
But, is there any problem with such a guideline?
One possible problem is that all disposable object will have a finalizer defined. But since the finalizer is always suppressed, there should not be any performance penalties.
What are your thoughts?
IDisposable is an interface that contains a single method, Dispose(), for releasing unmanaged resources, like files, streams, database connections and so on.
For implementing the IDisposable design pattern, the class which deals with unmanaged objects directly or indirectly should implement the IDisposable interface. And implement the method Dispose declared inside of the IDisposable interface. We do not directly deal with unmanaged objects.
IDisposable is defined in the System namespace. It provides a mechanism for releasing unmanaged resources. When your application or class library encapsulates unmanaged resources such as files, fonts, streams, database connections, etc, they should implement the IDisposable interface or the IAsyncDisposable interface.
You never know when the garbage collector will collect your object. You don't even know if it even will (unlike using delete in C++, which is deterministic). So IDisposable is there for deterministically releasing unneeded references (and releasing unmanaged resources).
does it make sense to have a guideline to force developers to derive from the following abstract class
No, solely for the reason that C# doesn't have multiple inheritance. Interfaces describe behavior, inheritance dictates "is-a". You'll thoroughly limit the object-oriented design of your classes if you enforce this rule.
For example you can't introduce base classes for business objects that are not disposable, where a derived class would be.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With