Нужно ли использовать ключевое слово «using» в каждом объекте, который реализует IDisposable? - PullRequest
5 голосов
/ 09 февраля 2012

Я звоню в стороннюю библиотеку, где многие классы реализовали IDisposable.

Нужно ли использовать шаблон для всех?

Ответы [ 4 ]

5 голосов
/ 09 февраля 2012

У вас нет до, но это хорошая практика.

Это обеспечивает правильную очистку ресурсов независимо от того, возникают исключения или нет.

IDisposableдолжны быть реализованы только на классах, которые должны очищать ресурсы, поэтому обеспечение их выполнения является хорошей практикой.

Могут быть случаи, когда потребуется вызов Dispose напрямую вместо использования блока (прокси WCF печально известныдля этого), но это не общий случай.

Короче говоря - никто не заставит вас использовать их, но вы действительно должны.

3 голосов
/ 09 февраля 2012

Это очень сильно зависит от области действия рассматриваемой переменной.

Локальная область: использование

Если переменная находится в локальной области, да, вы должны заключить соответствующий код в using блок.Помните, что блок using является всего лишь синтаксическим сахаром для следующего, предполагая, что using заключает в себе IDisposable объект с именем obj:

var obj = // ...
try
{
    // ...
}
finally
{
    obj.Dispose();
}

Это означает, что даже если выдается исключение, ваш объектбудет удален.

Область действия класса: IDisposable

Если ваш объект ограничен на уровне класса, то нет, вы не должны заключать его в блок using.Скорее, ваш класс должен предоставлять метод Dispose любому коду, который его использует, реализуя IDisposable и располагать объект там.

Никогда не использовать: Finalize

Как правило, это плохопрактиковаться в передаче ответственности за удаление сборщику мусора в любой точке этой цепочки зависимостей, полагаясь на финализатор класса для удаления его объектов.Это подрывает разницу между Dispose и Finalize: Dispose для явного немедленного освобождения ресурса, тогда как Finalize более пассивен.Полагаясь на Finalize для вызова Dispose, вы подрываете это разделение целей.Тем не менее, это больше вопрос стиля программирования с моей стороны, и представляет собой мнение - не принимайте это как факт.Вы должны исследовать это больше самостоятельно - и, конечно, прочитать неизбежный массив входящих комментариев по этому вопросу - прежде чем принимать мой совет.Я уверен, что пропустил важные исключения, по крайней мере.

3 голосов
/ 09 февраля 2012

Вам «не нужно» делать это, но вам, скорее всего, следует.

Если вы этого не сделаете, у вас могут кончиться некоторые ресурсы или вы можете даже получить неправильные результатыв зависимости от того, что именно делает эта библиотека.

Но, не зная, что именно делает Dispose() для этих объектов, вы должны определенно вызывать ее, чтобы избежать неожиданных проблем.(И вам не нужно делать это напрямую, вы можете использовать using, чтобы сделать это, как вы предложили.)

0 голосов
/ 09 февраля 2012

Когда класс реализует IDisposable, он говорит, что он скорее будет удален вашим кодом, чем будет ждать, пока сборщик мусора не удалит его позже. Так что да, если класс реализует IDisposable, вы должны вызвать Dispose (или использовать using), прежде чем он выйдет из области видимости.

Следует ли вам использовать использование вместо вызова Dispose напрямую? Опять да. Чтобы гарантировать удаление объекта, вы должны убедиться, что ваши объекты были удалены, даже если было сгенерировано исключение, путем инкапсуляции вашего кода в блоке try {...} finally {}, который будет располагать ваши объекты в блоке finally. Это приводит к ненужному беспорядку, и вы можете легко забыть добавить блок finally.

Гораздо безопаснее использовать для этой работы.

...