Rather than thinking in terms of an IDisposable
contract, it's more helpful to think of IDisposable
as being part of a general Object
contract which says that objects should not require any form of notice other than IDisposable.Dispose
before they are abandoned (objects which don't implement IDisposable
should not require any sort of notice at all). The Dispose
method should do anything and everything that needs to be done before an object can be safely abandoned.
The only aspect of this which is problematical is that exceptions may occur while performing cleanup, and there's no way for Dispose
to know what it should do in such case. If Dispose
is called during normal (non-exceptional) program execution, it should throw an exception if cleanup fails. If it is called while unwinding the stack from from an exception, however, any exception it might throw would generally destroy all evidence of the earlier exception (thus is would often be better for it to fail silently than throw an exception). Unfortunately, there's no way via which Dispose
can tell which situation applies, and thus no way for it to consistently do the right thing in case of cleanup failure.