Sobes.tech
Middle

Cos'è l'interfaccia IDisposable e a cosa serve in C#?

sobes.tech AI

Risposta dell'AI

IDisposable — è un'interfaccia che fornisce un meccanismo per liberare risorse non gestite. Contiene un metodo Dispose().

Viene utilizzata per:

  • Rilasciare risorse non gestite: come descrittori di file, connessioni a database, socket di rete. .NET non può gestire automaticamente queste risorse.
  • Pulizia dopo l'uso: garantisce che gli oggetti che consumano molte risorse vengano correttamente liberati, anche in presenza di eccezioni.
  • Utilizzo con l'operatore using: l'operatore using chiama automaticamente il metodo Dispose() al termine del blocco di codice, anche in caso di eccezioni. È il modo preferito di usare oggetti che implementano IDisposable.

Esempio di implementazione:

public class MyResource : IDisposable
{
    // Simulazione di una risorsa non gestita
    private bool isDisposed = false;
    private IntPtr unmanagedPointer;

    public MyResource()
    {
        // Assegnazione di una risorsa non gestita
        unmanagedPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(100);
    }

    // Metodo Dispose dell'interfaccia IDisposable
    public void Dispose()
    {
        Dispose(true);
        // Sopprime la finalizzazione, poiché le risorse sono già state liberate
        GC.SuppressFinalize(this);
    }

    // Metodo virtuale per implementare la logica di rilascio
    protected virtual void Dispose(bool disposing)
    {
        if (!isDisposed)
        {
            if (disposing)
            {
                // Rilascio delle risorse gestite, se presenti
                // ...
            }

            // Rilascio delle risorse non gestite
            System.Runtime.InteropServices.Marshal.FreeHGlobal(unmanagedPointer);
            unmanagedPointer = IntPtr.Zero;

            isDisposed = true;
        }
    }

    // Finalizzatore (distruttore) per il rilascio delle risorse se Dispose non è stato chiamato esplicitamente
    ~MyResource()
    {
        Dispose(false);
    }
}

Esempio di utilizzo con using:

using (var resource = new MyResource())
{
    // Lavoro con la risorsa
    // ...
} // Dispose() viene chiamato automaticamente all'uscita dal blocco using