Вся идея IDisposable заключается в том, что классы, которые реализуют, будут делать все необходимое для «разумной» очистки, если вызывается метод IDisposable.Dispose. Точное действие, выполняемое Dispose, может варьироваться в зависимости от состояния объекта и может не всегда соответствовать желаемому стилю очистки. Например, объект команды / транзакции может выполнить откат, если он удаляется без предварительного вызова метода «commit». Это вернет команду / транзакцию в «безопасное» состояние, но не обязательно такое, которое было предназначено.
Обратите также внимание, что обработка ошибок может отличаться в случаях, включающих явное «закрытие», детерминистическое «удаление» или недетерминированное «завершение» (в результате отказа от объекта). Семантически ясно, что операция «закрыть», которая не приводит к тому, что закрытый объект находится в правильном состоянии, должна вызвать исключение. Менее ясно, что метод Dispose должен это делать. (*) Некоторые классы будут выбрасывать после неудачного удаления, а другие - нет. Если объект заброшен и возникает проблема во время финализации, лишь немногие классы предоставят какое-либо уведомление, так как нет хорошего механизма для его решения. Если операция «закрыть» в конце сохранения документа завершается неудачно из-за того, что кто-то слишком быстро извлек USB-накопитель, приложение может сообщить пользователю, что документ не сохранен, и пользователь может действовать соответствующим образом. Если приложение откажется от файлового объекта, поэтому операция «закрыть» не произойдет до тех пор, пока через некоторое время USB-накопитель не будет удален, приложение не сможет справиться с ошибкой. В первом случае программа может предложить пользователю повторить попытку сохранения документа, но в последнем случае документ может исчезнуть.
(*) Если нет исключения, ожидающего, когда происходит Dispose, и Dispose не может выполнить требуемую очистку, довольно ясно, что должно быть сгенерировано исключение. С другой стороны, если исключение уже находится на рассмотрении, выброс из Dispose уничтожит всю информацию, содержащуюся в предыдущем исключении. Мой предпочтительный стиль - использовать метод Dispose (Exception Ex), который будет передавать Ex как внутреннее исключение в случае сбоя Dispose, но без поддержки языка такая вещь может поддерживаться только с неловким синтаксисом в vb.net и с сомнительным поведением в C #.