Sobes.tech
Middle

Šta je interfejs IDisposable i zašto se koristi u C#?

sobes.tech АИ

Одговор од АИ

IDisposable — ovo je interfejs koji pruža mehanizam za oslobađanje neuređenih resursa. Sadrži metodu Dispose().

Koristi se za:

  • Oslobađanje neuređenih resursa: poput deskriptora fajlova, veza sa bazama podataka, mrežnih soketa. .NET ne može automatski upravljati ovim resursima.
  • Čišćenje nakon upotrebe: garantuje da objekti koji troše mnogo resursa budu pravilno oslobođeni, čak i ako dođe do izuzetaka.
  • Korišćenje sa operatorom using: operator using automatski poziva metodu Dispose() na kraju bloka koda, čak i ako dođe do izuzetka. Ovo je preferirani način korišćenja objekata koji implementiraju IDisposable.

Primer implementacije:

public class MyResource : IDisposable
{
    // Simulacija neuređenog resursa
    private bool isDisposed = false;
    private IntPtr unmanagedPointer;

    public MyResource()
    {
        // Dodeljivanje neuređenog resursa
        unmanagedPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(100);
    }

    // Metoda Dispose iz interfejsa IDisposable
    public void Dispose()
    {
        Dispose(true);
        // Potiskivanje finalizacije, jer su resursi već oslobođeni
        GC.SuppressFinalize(this);
    }

    // Virtuelna metoda za implementaciju logike oslobađanja
    protected virtual void Dispose(bool disposing)
    {
        if (!isDisposed)
        {
            if (disposing)
            {
                // Oslobađanje upravljanih resursa, ako ih ima
                // ...
            }

            // Oslobađanje neuređenih resursa
            System.Runtime.InteropServices.Marshal.FreeHGlobal(unmanagedPointer);
            unmanagedPointer = IntPtr.Zero;

            isDisposed = true;
        }
    }

    // Finalizator (destruktor) za oslobađanje resursa ako `Dispose` nije eksplicitno pozvan
    ~MyResource()
    {
        Dispose(false);
    }
}

Primer korišćenja sa using:

using (var resource = new MyResource())
{
    // Rad sa resursom
    // ...
} // `Dispose()` se automatski poziva pri izlasku iz `using` bloka