Sobes.tech
Middle

O que é a interface IDisposable e para que é usada em C#?

sobes.tech IA

Resposta da IA

IDisposable — é uma interface que fornece um mecanismo para libertar recursos não geridos. Ela contém um método Dispose().

É utilizada para:

  • Libertar recursos não geridos: como descritores de ficheiros, ligações a bases de dados, sockets de rede. .NET não consegue gerir automaticamente esses recursos.
  • Limpeza após uso: garante que objetos que consomem muitos recursos sejam libertados corretamente, mesmo que ocorram exceções.
  • Uso com o operador using: o operador using chama automaticamente o método Dispose() ao terminar o bloco de código, mesmo que ocorra uma exceção. É a forma preferencial de usar objetos que implementam IDisposable.

Exemplo de implementação:

public class MyResource : IDisposable
{
    // Simulação de recurso não gerido
    private bool isDisposed = false;
    private IntPtr unmanagedPointer;

    public MyResource()
    {
        // Alocação de recurso não gerido
        unmanagedPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(100);
    }

    // Método Dispose da interface IDisposable
    public void Dispose()
    {
        Dispose(true);
        // Anula a finalização, pois os recursos já foram libertados
        GC.SuppressFinalize(this);
    }

    // Método virtual para implementar a lógica de libertação
    protected virtual void Dispose(bool disposing)
    {
        if (!isDisposed)
        {
            if (disposing)
            {
                // Libertar recursos geridos, se existirem
                // ...
            }

            // Libertar recursos não geridos
            System.Runtime.InteropServices.Marshal.FreeHGlobal(unmanagedPointer);
            unmanagedPointer = IntPtr.Zero;

            isDisposed = true;
        }
    }

    // Finalizador (destruidor) para libertar recursos se Dispose não foi chamado explicitamente
    ~MyResource()
    {
        Dispose(false);
    }
}

Exemplo de uso com using:

using (var resource = new MyResource())
{
    // Trabalhar com o recurso
    // ...
} // Dispose() é chamado automaticamente ao sair do bloco using