Sobes.tech
Middle

Czym jest interfejs IDisposable i do czego służy w C#?

sobes.tech AI

Odpowiedź od AI

IDisposable — to interfejs zapewniający mechanizm zwalniania niezarządzanych zasobów. Zawiera metodę Dispose().

Jest używany do:

  • Zwalniania niezarządzanych zasobów: takich jak deskryptory plików, połączenia z bazami danych, gniazda sieciowe. .NET nie potrafi automatycznie zarządzać tymi zasobami.
  • Czyszczenia po użyciu: zapewnia, że zasobożerne obiekty zostaną poprawnie zwolnione, nawet jeśli wystąpią wyjątki.
  • Współużytkowania z operatorem using: operator using automatycznie wywołuje metodę Dispose() po zakończeniu bloku kodu, nawet jeśli wystąpi wyjątek. To preferowany sposób korzystania z obiektów implementujących IDisposable.

Przykład implementacji:

public class MyResource : IDisposable
{
    // Symulacja niezarządzanego zasobu
    private bool isDisposed = false;
    private IntPtr unmanagedPointer;

    public MyResource()
    {
        // Przydzielenie niezarządzanego zasobu
        unmanagedPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(100);
    }

    // Metoda Dispose z interfejsu IDisposable
    public void Dispose()
    {
        Dispose(true);
        // Zapobieganie finalizacji, ponieważ zasoby już zwolniono
        GC.SuppressFinalize(this);
    }

    // Wirtualna metoda do implementacji logiki zwalniania
    protected virtual void Dispose(bool disposing)
    {
        if (!isDisposed)
        {
            if (disposing)
            {
                // Zwolnienie zarządzanych zasobów, jeśli istnieją
                // ...
            }

            // Zwolnienie niezarządzanych zasobów
            System.Runtime.InteropServices.Marshal.FreeHGlobal(unmanagedPointer);
            unmanagedPointer = IntPtr.Zero;

            isDisposed = true;
        }
    }

    // Finalizator (destruktor) do zwalniania zasobów, jeśli Dispose nie został wywołany jawnie
    ~MyResource()
    {
        Dispose(false);
    }
}

Przykład użycia z using:

using (var resource = new MyResource())
{
    // Praca z zasobem
    // ...
} // Dispose() jest wywoływane automatycznie przy wyjściu z bloku using