Menu
Coddy logo textTech

IDisposable i instrukcja using

Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 45 z 70.

Niektóre obiekty przechowują zasoby, których garbage collector nie może automatycznie zwolnić — uchwyty plików, połączenia z bazą danych, gniazda sieciowe. Interfejs IDisposable zapewnia standardowy sposób zwalniania tych zasobów, gdy już ich nie potrzebujesz.

Klasa implementuje IDisposable, udostępniając metodę Dispose():

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

Możesz wywołać Dispose() ręcznie, ale co, jeśli wyjątek wystąpi, zanim dotrzesz do tej linii? Instrukcja using gwarantuje sprzątanie nawet wtedy, gdy coś pójdzie nie tak:

using (FileHandler handler = new FileHandler())
{
    // Pracuj z obiektem handler
}  // Dispose() jest tutaj wywoływana automatycznie

Nowoczesny C# oferuje czytelniejszą składnię dzięki deklaracji using, która zwalnia obiekt, gdy wykracza on poza zakres:

void ProcessFile()
{
    using FileHandler handler = new FileHandler();
    // Pracuj z handler
}  // Dispose() jest wywoływane przy zakończeniu metody

Instrukcja using działa z każdym typem implementującym IDisposable. Wbudowane klasy, takie jak StreamReader, SqlConnection i HttpClient, implementują ten interfejs, dzięki czemu prawidłowe zarządzanie zasobami jest proste i niezawodne.

challenge icon

Wyzwanie

Łatwy

Zbudujmy symulator połączenia z bazą danych, który demonstruje prawidłowe zarządzanie zasobami za pomocą interfejsu IDisposable i instrukcji using. Utworzysz klasę, która śledzi, kiedy połączenia są otwierane i zamykane, zapewniając prawidłowe zwalnianie zasobów.

Rozmieścisz kod w dwóch plikach:

  • DatabaseConnection.cs: Utwórz klasę DatabaseConnection w przestrzeni nazw DataAccess, która implementuje IDisposable. Twoje połączenie powinno:
    • Mieć właściwość ConnectionName (string, tylko do odczytu), ustawianą przez konstruktor
    • Śledzić, czy połączenie zostało zwolnione, za pomocą prywatnego pola logicznego
    • Wypisywać Connection opened: {ConnectionName} podczas tworzenia obiektu (w konstruktorze)
    • Implementować metodę Dispose(), która wypisuje Connection closed: {ConnectionName} — ale tylko wtedy, gdy zasób nie został jeszcze zwolniony (zapobieganie wielokrotnemu zwalnianiu)
    • Mieć metodę Query(string sql), która zwraca Executing on {ConnectionName}: {sql}
  • Program.cs: W pliku głównym zademonstruj prawidłowe zarządzanie zasobami, używając instrukcji using z połączeniem z bazą danych. Utwórz połączenie, wykonaj zapytanie i pozwól, aby blok using automatycznie zajął się sprzątaniem.

Otrzymasz dwa dane wejściowe:

  • Nazwę połączenia (np. MainDB)
  • Zapytanie SQL do wykonania (np. SELECT * FROM Users)

Użyj instrukcji using, aby utworzyć połączenie. Wewnątrz bloku wywołaj metodę Query i wypisz jej wynik. Po zakończeniu bloku using metoda Dispose() zostanie wywołana automatycznie.

Na przykład, jeśli dane wejściowe to MainDB i SELECT * FROM Users, wynikiem powinno być:

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

Zauważ, że połączenie jest automatycznie zamykane po zakończeniu bloku using — nigdy nie musisz pamiętać o ręcznym wywołaniu Dispose(). Ten wzorzec zapewnia prawidłowe zwalnianie zasobów, nawet jeśli wewnątrz bloku wystąpi wyjątek!

Spróbuj swoich sił

using System;
using DataAccess;

class Program
{
    public static void Main(string[] args)
    {
        string connectionName = Console.ReadLine();
        string sqlQuery = Console.ReadLine();
        
        // TODO: Użyj instrukcji 'using', aby utworzyć DatabaseConnection
        // Wewnątrz bloku using:
        // 1. Wywołaj metodę Query z argumentem sqlQuery
        // 2. Wypisz wynik metody Query
        // Metoda Dispose zostanie wywołana automatycznie po zakończeniu bloku using
        
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C# online