// Вызовы этих методов делают одно и то же!
fs.Close();
fs.Dispose();
}
В то время как "закрытие" (close) файла выглядит более естественным, чем его "освобождение" (dispose), подобное дублирование методов очистки может запутывать. При работе с типами, предлагающими псевдонимы, просто помните о том, что если тип реализует интерфейс IDisposable
Dispose() всегда является безопасным способом действия.Повторное использование ключевого слова using в C#
Имея дело с управляемым объектом, который реализует интерфейс IDisposable
Dispose() типа будет вызываться даже в случае генерации исключения во время выполнения:Console.WriteLine("***** Fun with Dispose *****\n");
MyResourceWrapper rw = new MyResourceWrapper ();
try
{
// Использовать члены rw.
}
finally
{
// Всегда вызывать Dispose(), возникла ошибка или нет.
rw.Dispose();
}
Хотя это является хорошим примером защитного программирования, в действительности лишь немногих разработчиков привлекает перспектива помещения каждого освобождаемого типа внутрь блока try/finally
Dispose(). Того же самого результата можно достичь гораздо менее навязчивым способом, используя специальный фрагмент синтаксиса С#, который выглядит следующим образом:Console.WriteLine("***** Fun with Dispose *****\n");
// Метод Dispose() вызывается автоматически
// при выходе за пределы области действия using.
using(MyResourceWrapper rw = new MyResourceWrapper())
{
// Использовать объект rw.
}
Если вы просмотрите код CIL операторов верхнего уровня посредством ildasm.exe
using на самом деле расширяется до логики try/finally с вполне ожидаемым вызовом Dispose():.method private hidebysig static void
'
{
...
.try
{
} // end .try
finally
{
IL_0019: callvirt instance void [System.Runtime]System.IDisposable::Dispose()
} // end handler
} // end of method '
На заметку!
Попытка примененияusing к объекту, который не реализует интерфейс IDisposable, приводит к ошибке на этапе компиляции.Несмотря на то что такой синтаксис устраняет необходимость вручную помещать освобождаемые объекты внутрь блоков try/finally
using в C# имеет двойной смысл (импортирование пространств имен и вызов метода Dispose()). Однако при работе с типами, которые поддерживают интерфейс IDisposable, такая синтаксическая конструкция будет гарантировать, что используемый объект автоматический вызовет свой метод Dispose() по завершении блока using.Кроме того, имейте в виду, что внутри using
Dispose() на каждом объявленном объекте:// Использовать список с разделителями-запятыми для объявления
// нескольких объектов, подлежащих освобождению.
using(MyResourceWrapper rw = new MyResourceWrapper(),
rw2 = new MyResourceWrapper())
{
// Работать с объектами rw и rw2.
}
Объявления using (нововведение в версии 8.0)
В версии C# 8.0 были добавлены объявления using
using представляет собой объявление переменной, предваренное ключевым словом using. Функциональность объявления using будет такой же, как у синтаксиса, описанного в предыдущем разделе, за исключением явного блока кода, помещенного внутрь фигурных скобок ({}).Добавьте к своему классу следующий метод:
private static void UsingDeclaration()
{
// Эта переменная будет находиться в области видимости
// вплоть до конца метода.
using var rw = new MyResourceWrapper();