Разница между "использованием" и определением области действия?
Вопрос
В чем разница между следующими двумя фрагментами кода:
using (Object o = new Object())
{
// Do something
}
и
{
Object o = new Object();
// Do something
}
Я начал использовать using
намного больше, но мне любопытно, каковы на самом деле преимущества по сравнению с объектами области видимости.
Редактировать: Полезные лакомые кусочки, которые я извлек из этого:
Джон Скит:
Обратите внимание, что это никоим образом не приводит к принудительной сборке мусора в какой-либо форме.Сборка мусора и оперативная очистка ресурсов несколько ортогональны.
Прокомментирует ли Эддинс:
Если ваш класс не реализует интерфейс IDisposable и не имеет функции Dispose(), вы не используете using .
Решение
Первый фрагмент вызывает Dispose
в конце блока - вы можете сделать это только с типами, которые реализуют IDisposable
, и это в основном вызывает Dispose
в блоке finally, чтобы вы могли использовать его с типами, которые нуждаются в очистке ресурсов, например
using (TextReader reader = File.OpenText("test.txt"))
{
// Use reader to read the file
}
// reader will be disposed, so file handle released
Обратите внимание, что это делает не принудительно соберите мусор любым способом, в любой форме.Сборка мусора и оперативная очистка ресурсов несколько ортогональны.
В принципе, вы должны использовать using
оператор практически для всего, что реализует IDisposable
и за который ваш блок кода собирается взять на себя ответственность (с точки зрения очистки).
Другие советы
В конце using
объект будет удален (объект, который вы помещаете внутрь круглой скобки, должен реализовывать IDisposable).Объект удаляется также в исключительных случаях.И вам не нужно ждать, пока GC сделает это в какой-то момент (вы контролируете это).
Редактировать:Недостатками определения области видимости являются:
- вы не контролируете расположение объекта
- даже если бы вы вызвали dispose в конце вашей области видимости, это не было бы безопасным для исключений
Просто чтобы буквально показать разницу...
using (FileStream fileStream = new FileStream("log.txt", FileMode.OpenCreate))
{
//stuff with file stream
}
это то же самое, что и...
{
FileStream fileStream = new FileStream("log.txt", FileMode.OpenCreate);
try
{
//stuff with filestream
}
finally
{
if (fileStream != null)
((IDisposable)fileStream).Dispose();
}
}
где как
{
FileStream fileStream = new FileStream("log.txt", FileMode.OpenCreate);
fileStream.Dispose();
}
есть так, как оно есть.
Смотрите документацию, касающуюся IDisposable ( подлежащий удалению ) и определяемое освобождение ресурсов.
Проще говоря, в конце using{}
блокировать, вы можете надежно распоряжаться выделенными ресурсами (например,закройте дескрипторы файлов, подключения к базе данных и т.д.)
using
просто требуется реализация интерфейса IDisposable и вызывает метод Dispose в конце области видимости.
Для множества яростных споров о правильном размещении объектов есть множество других тем.