Ответ
Конструкция using компилируется в блок try-finally, который гарантирует вызов метода Dispose() для объекта, реализующего интерфейс IDisposable, даже в случае возникновения исключения.
Исходный код:
using (var resource = new SomeDisposableResource())
{
// Работа с ресурсом
resource.DoSomething();
}
Примерный код после компиляции (декомпиляция):
SomeDisposableResource resource = new SomeDisposableResource();
try
{
// Работа с ресурсом
resource.DoSomething();
}
finally
{
if (resource != null)
{
((IDisposable)resource).Dispose();
}
}
Ключевые моменты:
- Гарантия очистки: Блок
finallyвыполняется всегда, что предотвращает утечку неуправляемых ресурсов (дескрипторы файлов, сокеты, соединения с БД). - Требование: Переменная в
usingдолжна иметь тип, реализующийIDisposable. - Начиная с C# 8.0 доступен
usingобъявления, где область действия ресурса — до конца текущего блока.using var resource = new SomeDisposableResource(); // Работа с ресурсом // Dispose() будет вызван автоматически при выходе из метода/блока. - Асинхронный аналог: Для объектов, реализующих
IAsyncDisposable(например,DbContextв EF Core), используйтеawait using.await using (var connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); // ... } // Будет вызван await connection.DisposeAsync()
Важно: using не заменяет обработку исключений для операций внутри блока, он гарантирует только освобождение ресурса.