← Все вопросы

Что такое IDisposable и зачем нужен using в C#?

Задан 9 месяцев назад1.2к просмотров2 ответа
8

Постоянно вижу using (var conn = ...) и интерфейс IDisposable. Что они делают и почему нельзя просто положиться на сборщик мусора?

using (var file = new StreamReader("data.txt"))
{
    // ...
}

2 ответа

15
✓ Принятый ответ — помог автору

GC освобождает только управляемую память. Но есть неуправляемые ресурсы — файловые дескрипторы, сетевые сокеты, подключения к БД — которые GC сам не закроет вовремя (а то и вообще). За них отвечает IDisposable.

IDisposable — это интерфейс с единственным методом Dispose(), где вы освобождаете такие ресурсы. А using гарантирует, что Dispose() вызовется всегда, даже если внутри блока вылетит исключение.

// using разворачивается в try/finally:
var file = new StreamReader("data.txt");
try
{
    Console.WriteLine(file.ReadToEnd());
}
finally
{
    file.Dispose(); // вызовется в любом случае
}

С C# 8 есть короткий синтаксис без фигурных скобок — ресурс освободится в конце области видимости:

using var file = new StreamReader("data.txt");
Console.WriteLine(file.ReadToEnd());
// Dispose() здесь, на выходе из метода

Правило: всё, что реализует IDisposable, оборачивайте в using.

5

Если пишете свой класс с неуправляемыми ресурсами, реализуйте IDisposable так:

public class Resource : IDisposable
{
    private bool _disposed;
    public void Dispose()
    {
        if (_disposed) return;
        // освобождаем ресурсы
        _disposed = true;
        GC.SuppressFinalize(this);
    }
}

Для асинхронного освобождения (например, потоков) есть IAsyncDisposable и await using.

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект