Есть разные допустимые варианты использования IDisposable
. Простой пример - открытый файл, который нужно закрыть в определенный момент, как только он вам больше не понадобится. Конечно, вы можете предоставить метод Close
, но наличие его в Dispose
и использование такого шаблона, как using (var f = new MyFile(path)) { /*process it*/ }
, было бы более безопасным для исключений.
Более популярный пример - это хранение некоторых других IDisposable
ресурсов, что обычно означает, что вам нужно предоставить свои собственные Dispose
, чтобы их также можно было удалить.
В общем, как только вы хотите добиться детерминированного уничтожения чего-либо, вам нужно реализовать IDisposable
.
Разница между моим и вашим мнением заключается в том, что я реализую IDisposable
, как только некоторый ресурс требует детерминированного уничтожения / освобождения, а не обязательно как можно скорее. В этом случае нельзя полагаться на сборку мусора (вопреки утверждениям вашего коллеги), потому что это происходит в непредсказуемый момент времени и на самом деле может не произойти вовсе!
Тот факт, что какой-либо ресурс неуправляемый под прикрытием, на самом деле ничего не значит: разработчик должен думать в терминах «когда и как правильно избавиться от этого объекта», а не «как он работает под прикрытием». Базовая реализация в любом случае может измениться со временем.
Фактически, одно из основных различий между C # и C ++ - отсутствие детерминированного уничтожения по умолчанию. IDisposable
закрывает пробел: вы можете приказать детерминированное уничтожение (хотя вы не можете гарантировать, что клиенты его вызывают; точно так же в C ++ вы не можете быть уверены, что клиенты вызывают delete
на объекте).
Небольшое дополнение: в чем на самом деле разница между детерминированным освобождением ресурсов и их освобождением как можно скорее? Собственно, это разные (хотя и не совсем ортогональные) понятия.
Если ресурсы должны быть освобождены детерминированно, это означает, что клиентский код должен иметь возможность сказать: «Теперь я хочу освободить этот ресурс». На самом деле это может быть не самый ранний возможный момент, когда ресурс может быть освобожден: объект, содержащий ресурс, мог получить все, что ему нужно, от ресурса, поэтому потенциально он может уже освободить ресурс. С другой стороны, объект может выбрать сохранение (обычно неуправляемого) ресурса даже после того, как объект Dispose
прошел через него, очищая его только в финализаторе (если удерживание ресурса слишком долгое время не вызывает никаких проблем).
Итак, для освобождения ресурса как можно скорее, строго говоря, Dispose
не требуется: объект может освободить ресурс, как только он осознает, что ресурс больше не нужен. Dispose
, однако, служит полезным намеком на то, что объект сам больше не нужен, поэтому, возможно, ресурсы могут быть освобождены на этом этапе, если это необходимо.
Еще одно необходимое дополнение: детерминированное освобождение требуется не только для неуправляемых ресурсов! Это, кажется, один из ключевых моментов расхождения во мнениях между ответами на этот вопрос. Можно иметь чисто образную конструкцию, которую, возможно, нужно будет детерминистически освободить.
Примеры: право на доступ к некоторой совместно используемой структуре (подумайте, RW-lock), огромный кусок памяти (представьте, что вы управляете частью памяти программы вручную), лицензию на использование какой-либо другой программы (представьте, что вам не разрешено запускать более X копии некоторой программы одновременно) и т. д. Здесь освобождаемый объект - это не неуправляемый ресурс, а право что-то делать / использовать, что является чисто внутренней конструкцией логики вашей программы.
Небольшое дополнение: вот небольшой список изящных примеров использования [ab] IDisposable
: http://www.introtorx.com/Content/v1.0.10621.0/03_LifetimeManagement.html#IDisposable.
person
Vlad
schedule
25.04.2012
IDisposable
, помимо неуправляемых ресурсов, - это когда мне нужно убедиться, что события отписываются должным образом, чтобы класс можно было собрать с помощью сборщика мусора. Но это действительно провал языка: события ДЕЙСТВИТЕЛЬНО ДЕЙСТВИТЕЛЬНО должны быть слабыми ссылками, но это не так. - person BlueRaja - Danny Pflughoeft   schedule 06.07.2012