I'm going out on a limb here, but... most people don't need the full-blown dispose pattern. It's designed to be solid in the face of having direct access to unmanaged resources (usually via IntPtr
) and in the face of inheritance. Most of the time, neither of these is actually required.
If you're just holding a reference to something else which implements IDisposable
, you almost certainly don't need a finalizer - whatever holds the resource directly is responsible for dealing with that. You can make do with something like this:
public sealed class Foo : IDisposable
{
private bool disposed;
private FileStream stream;
// Other code
public void Dispose()
{
if (disposed)
{
return;
}
stream.Dispose();
disposed = true;
}
}
Note that this isn't thread-safe, but that probably won't be a problem.
By not having to worry about the possibility of subclasses holding resources directly, you don't need to suppress the finalizer (because there isn't one) - and you don't need to provide a way of subclasses customising the disposal either. Life is simpler without inheritance.
If you do need to allow uncontrolled inheritance (i.e. you're not willing to bet that subclasses will have very particular needs) then you need to go for the full pattern.
Note that with SafeHandle
from .NET 2.0, it's even rarer that you need your own finalizer than it was in .NET 1.1.
To address your point about why there's a disposing
flag in the first place: if you're running within a finalizer, other objects you refer to may already have been finalized. You should let them clean up themselves, and you should only clean up the resources you directly own.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…