Forgive me in advance if this question is too frank, but I saw similar posts about the discussions here, so I decided that I would take a decisive step.
Anyway, I read several MSDN help pages and various other blogs on the proper use of IDisposable
classes. I feel like I'm good at things, but I need to wonder if there is a flaw in the proposed class structure:
public class DisposableBase : IDisposable { private bool mDisposed; ~DisposableBase() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!mDisposed) { if (disposing) {
Anytime the above should serve as the base class, you rely on the executor of this subclass to override the Dispose (bool) method appropriately if necessary. In short, derived classes must ensure that they invoke the base Dispose (bool) method from their overridden version. If not, the unmanaged resources of the base class can never be freed, which will lead to victory over the main goal of the IDisposable interface.
We all know the advantages of virtual methods, but it seems that in this case their design does not justify itself. In fact, I think this drawback of virtual methods often manifests itself when trying to design visual components and similar structures of base / derived classes.
Consider the following change using a protected event rather than a protected virtual method:
public class DisposeEventArgs : EventArgs { public bool Disposing { get; protected set; } public DisposeEventArgs(bool disposing) { Disposing = disposing; } } public class DisposableBase : IDisposable { private bool mDisposed; protected event EventHandler<DisposeEventArgs> Disposing; ~DisposableBase() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); }
In this design, the Dispose (bool) base class method will always be called, regardless of whether the subclasses signed for the Disposing event or not. The biggest drawback that I see in this redesigned setting is that there is no predefined order when event listeners are called. This can be problematic if there are several levels of inheritance, for example. A SubclassA listener can be started in front of its child SubclassB listener. Is this flaw serious enough to invalidate my revised design?
This design dilemma makes me wish there was some kind of modifier for methods that was similar to virtual
, but which would ensure that the base class method was always called, even if a subclass redefined this function. If there is a better way to achieve this, I will greatly appreciate your suggestions.