It may be safe to not cause Dispose , but the problem is to know when it is.
Good 95% of IEnumerator<T> implementations have Dispose , which can be ignored, but 5% is not only 5%, which will lead to an error, but 5%, which will lead to disgusting tracing of the error. Moreover, the code that receives the passed IEnumerator<T> will see both 95% and 5% and will not be able to dynamically separate them (it is possible to implement a non-generic IEnumerable without implementing IDisposable , and how well it turned out, we can assume that MS decided to make IEnumerator<T> inherit from IDisposable !).
Of the rest, maybe 3 or 4% of the time, when it is safe. Presently. You do not know that 3% does not look at the code, and even then the contract says that you should call it, so the developer can depend on you if they release a new version, where it is important.
Thus, it always calls Dispose() . (I can think of an exception, but it is frankly too strange, even going into details, and in this case it’s still safe to call it, and not vital).
On the issue of implementing IDisposable avoid the template in the damn document yourself.
I view this pattern as an anti-pattern. This is a good template for implementing both IDisposable.Dispose and the finalizer in a class that contains both managed and unmanaged resources. However, storing both managed IDisposable and unmanaged resources is, firstly, a bad idea.
Instead
If you have an unmanaged resource, then you do not have unmanaged resources that implement IDisposable . Now the Dispose(true) and Dispose(false) code codes are the same, so they really can become:
public class HasUnmanaged : IDisposable { IntPtr unmanagedGoo; private void CleanUp() { if(unmanagedGoo != IntPtr.Zero) { SomeReleasingMethod(unmanagedGoo); unmanagedGoo = IntPtr.Zero; } } public void Dispose() { CleanUp(); GC.SuppressFinalize(this); } ~HasUnmanaged() { CleanUp(); } }
If you manage the resources that need to be disposed of, just do this:
public class HasUnmanaged : IDisposable { IDisposable managedGoo; public void Dispose() { if(managedGoo != null) managedGoo.Dispose(); } }
There is no critical “disposing" bool (how can you call Dispose something and take false for something called disposing ?). Do not worry about finalizers for 99.99% of the time when you do not need them (the second sample is more common than the first). Things are good.
Do you really need something that has both a managed and unmanaged resource? No, in fact, you do not transfer an unmanaged resource to your own class, which works as a descriptor, and then this descriptor matches the first template above, and the main class is suitable for the second.
Use only the CA10634 pattern when you are forced because you inherited from the class that did this. Fortunately, most people no longer create new ones like that.