Sobes.tech
Middle

O que é o método Finalize em C#?

sobes.tech IA

Resposta da IA

O método Finalize em C# é um método virtual protegido da classe base System.Object, que é chamado pelo coletor de lixo (GC) imediatamente antes do objeto ser removido da memória.

O seu objetivo principal é libertar recursos não geridos (por exemplo, descritores de ficheiros, sockets de rede, ponteiros para memória não gerida), que não são controlados diretamente pelo .NET Framework.

Aqui estão alguns pontos-chave sobre Finalize:

  • Não é garantido que seja chamado. O GC pode não realizar a finalização do objeto se a aplicação terminar antes.
  • O momento de chamada de Finalize não é determinista. Não podemos saber exatamente quando o GC irá iniciar e chamar o método.
  • A execução de Finalize pode levar tempo, o que pode atrasar o trabalho do GC.
  • Recomenda-se evitar o uso de Finalize para libertar recursos, usando em vez disso a interface IDisposable e a instrução using.
  • Nas versões modernas de C# e .NET Framework, em vez de sobrescrever explicitamente Finalize, usa-se a sintaxe de destrutor (finalizador), que o compilador transforma numa sobrescrita de Finalize:
public class MyClassWithFinalizer
{
    // Destrutor - o compilador transforma-o numa método Finalize
    ~MyClassWithFinalizer()
    {
        // Código para libertar recursos não geridos
        // Por exemplo: CloseHandle(myUnmanagedHandle);
        System.Console.WriteLine("Finalizer called for MyClassWithFinalizer");
    }
}

A utilização de IDisposable em conjunto com Finalize implementa o padrão Dispose:

public class MyDisposableResource : IDisposable
{
    private bool disposed = false;
    // Simulação de recurso não gerido
    private System.IntPtr unmanagedResource;

    public MyDisposableResource()
    {
        // Simulação de alocação de recurso não gerido
        unmanagedResource = System.Runtime.InteropServices.Marshal.AllocHGlobal(1024);
        System.Console.WriteLine("Recurso não gerido alocado.");
    }

    // Método para libertar recursos
    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // Libertar recursos geridos se disposing == true
                // (não é necessário neste exemplo)
            }

            // Libertar recursos não geridos em qualquer caso
            if (unmanagedResource != System.IntPtr.Zero)
            {
                System.Runtime.InteropServices.Marshal.FreeHGlobal(unmanagedResource);
                unmanagedResource = System.IntPtr.Zero;
                System.Console.WriteLine("Recurso não gerido libertado.");
            }

            disposed = true;
        }
    }

    // Implementação de IDisposable
    public void Dispose()
    {
        Dispose(true);
        // Suprimir a chamada ao finalizador, pois os recursos já foram libertados
        System.GC.SuppressFinalize(this);
    }

    // Finalizador (destrutor) - mecanismo de reserva para libertar recursos não geridos
    ~MyDisposableResource()
    {
        Dispose(false);
        System.Console.WriteLine("Finalizer called (as a fallback).");
    }
}

Assim, Finalize é um mecanismo de última hipótese para libertar recursos não geridos, mas o seu uso deve ser minimizado em favor de IDisposable.