Menu
Coddy logo textTech

IDisposable и оператор using

Часть раздела Объектно-ориентированное программирование путешествия по C# на Coddy. Урок 45 из 70.

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

Класс implements IDisposable, предоставляя метод Dispose():

public class FileHandler : IDisposable
{
    private bool disposed = false;
    
    public void Dispose()
    {
        if (!disposed)
        {
            Console.WriteLine("Releasing resources...");
            disposed = true;
        }
    }
}

Вы могли бы вызвать Dispose() вручную, но что, если до этой строки произойдёт исключение? Инструкция using гарантирует выполнение очистки, даже если что-то пойдёт не так:

using (FileHandler handler = new FileHandler())
{
    // Работа с handler
}  // Dispose() вызывается автоматически здесь

Современный C# предлагает более чистый синтаксис с объявлением using, которое освобождает объект, когда он выходит из области видимости:

void ProcessFile()
{
    using FileHandler handler = new FileHandler();
    // Работа с handler
}  // Dispose() вызывается при выходе из метода

Инструкция using работает с любым типом, который реализует IDisposable. Встроенные классы, такие как StreamReader, SqlConnection и HttpClient, реализуют этот интерфейс, что делает правильное управление ресурсами простым и надёжным.

challenge icon

Задание

Легко

Давайте создадим симулятор подключения к базе данных, демонстрирующий правильное управление ресурсами с использованием интерфейса IDisposable и оператора using. Вы создадите class, отслеживающий момент открытия и закрытия подключений и гарантирующий, что ресурсы всегда освобождаются должным образом.

Вы организуете код в двух файлах:

  • DatabaseConnection.cs: создайте class DatabaseConnection в namespace DataAccess, который implements IDisposable. Ваше подключение должно:
    • иметь property ConnectionName (строка, доступная только для чтения), устанавливаемую через constructor
    • отслеживать, было ли подключение освобождено, с помощью private boolean field
    • выводить Connection opened: {ConnectionName} при создании объекта (в constructor)
    • реализовывать method Dispose(), выводящий Connection closed: {ConnectionName} — но only если объект ещё не был освобождён (чтобы prevent двойное освобождение)
    • иметь method Query(string sql), возвращающий Executing on {ConnectionName}: {sql}
  • Program.cs: в основном файле продемонстрируйте правильное управление ресурсами, используя оператор using вместе с подключением к базе данных. Создайте подключение, выполните запрос и позвольте блоку using автоматически выполнить очистку.

Вы получите два входных значения:

  • имя подключения (например, MainDB)
  • SQL-запрос для выполнения (например, SELECT * FROM Users)

Используйте оператор using для создания подключения. Inside блока вызовите method Query и выведите его результат. Когда блок using ends, Dispose() будет вызван automatically.

Например, если входными значениями являются MainDB и SELECT * FROM Users, вывод должен быть таким:

Connection opened: MainDB
Executing on MainDB: SELECT * FROM Users
Connection closed: MainDB

Обратите внимание, как подключение автоматически закрывается, когда блок using ends — вам never приходится помнить о необходимости вручную вызывать Dispose(). Этот шаблон гарантирует, что ресурсы всегда будут очищены, даже если внутри блока произойдёт исключение!

Попробуйте сами

using System;
using DataAccess;

class Program
{
    public static void Main(string[] args)
    {
        string connectionName = Console.ReadLine();
        string sqlQuery = Console.ReadLine();
        
        // TODO: Используйте оператор 'using' для создания DatabaseConnection
        // Внутри блока using:
        // 1. Вызовите метод Query с sqlQuery
        // 2. Выведите результат метода Query
        // Метод Dispose будет вызван автоматически при завершении блока using
        
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор C#