Finalizadores (Guia de Programação em C#)Finalizers (C# Programming Guide)

Os finalizadores (que também são chamados de destruidores) são usados para executar qualquer limpeza final necessária, quando uma instância da classe está sendo coletada pelo coletor de lixo.Finalizers (which are also called destructors) are used to perform any necessary final clean-up when a class instance is being collected by the garbage collector.

ComentáriosRemarks

  • Os finalizadores não podem ser definidos em structs.Finalizers cannot be defined in structs. Eles são usados somente com classes.They are only used with classes.

  • Uma classe pode ter somente um finalizador.A class can only have one finalizer.

  • Os finalizadores não podem ser herdados ou sobrecarregados.Finalizers cannot be inherited or overloaded.

  • Os finalizadores não podem ser chamados.Finalizers cannot be called. Eles são invocados automaticamente.They are invoked automatically.

  • Um finalizador não usa modificadores ou não tem parâmetros.A finalizer does not take modifiers or have parameters.

Por exemplo, o seguinte é uma declaração de um finalizador para a classe Car.For example, the following is a declaration of a finalizer for the Car class.

class Car
{
    ~Car()  // finalizer
    {
        // cleanup statements...
    }
}

Um finalizador também pode ser implementado como uma definição do corpo da expressão, como mostra o exemplo a seguir.A finalizer can also be implemented as an expression body definition, as the following example shows.

using System;

public class Destroyer
{
   public override string ToString() => GetType().Name;
   
   ~Destroyer() => Console.WriteLine($"The {ToString()} destructor is executing.");
}

O finalizador chama implicitamente Finalize na classe base do objeto.The finalizer implicitly calls Finalize on the base class of the object. Portanto, uma chamada para um finalizador é convertida implicitamente para o código a seguir:Therefore, a call to a finalizer is implicitly translated to the following code:

protected override void Finalize()  
{  
    try  
    {  
        // Cleanup statements...  
    }  
    finally  
    {  
        base.Finalize();  
    }  
}  

Isso significa que o método Finalize é chamado de forma recursiva para todas as instâncias da cadeia de herança, da mais derivada à menos derivada.This means that the Finalize method is called recursively for all instances in the inheritance chain, from the most-derived to the least-derived.

Observação

Finalizadores vazios não devem ser usados.Empty finalizers should not be used. Quando uma classe contém um finalizador, uma entrada é criada na fila Finalize.When a class contains a finalizer, an entry is created in the Finalize queue. Quando o finalizador é chamado, o coletor de lixo é invocado para processar a fila.When the finalizer is called, the garbage collector is invoked to process the queue. Um finalizador vazio apenas resulta na perda de desempenho desnecessária.An empty finalizer just causes a needless loss of performance.

O programador não tem controle sobre quando o finalizador é chamado porque isso é determinado pelo coletor de lixo.The programmer has no control over when the finalizer is called because this is determined by the garbage collector. O coletor de lixo procura objetos que não estão mais sendo usados pelo aplicativo.The garbage collector checks for objects that are no longer being used by the application. Se considerar um objeto qualificado para finalização, ele chamará o finalizador (se houver) e recuperará a memória usada para armazenar o objeto.If it considers an object eligible for finalization, it calls the finalizer (if any) and reclaims the memory used to store the object.

Em aplicativos .NET Framework (mas não em aplicativos .NET Core), os finalizadores também são chamados quando o programa é encerrado.In .NET Framework applications (but not in .NET Core applications), finalizers are also called when the program exits.

É possível forçar a coleta de lixo chamando Collect, mas na maioria das vezes, isso deve ser evitado porque pode criar problemas de desempenho.It is possible to force garbage collection by calling Collect, but most of the time, this should be avoided because it may create performance issues.

Usar finalizadores para liberar recursosUsing finalizers to release resources

Em geral, o C# não demanda tanto gerenciamento de memória quanto é necessário quando você desenvolve usando uma linguagem que não tem como destino um tempo de execução com coleta de lixo.In general, C# does not require as much memory management as is needed when you develop with a language that does not target a runtime with garbage collection. Isso ocorre porque o coletor de lixo do .NET Framework gerencia implicitamente a alocação e a liberação de memória para seus objetos.This is because the .NET Framework garbage collector implicitly manages the allocation and release of memory for your objects. No entanto, quando seu aplicativo encapsula recursos não gerenciados, como janelas, arquivos e conexões de rede, você deve usar finalizadores para liberar esses recursos.However, when your application encapsulates unmanaged resources such as windows, files, and network connections, you should use finalizers to free those resources. Quando o objeto está qualificado para finalização, o coletor de lixo executa o método Finalize do objeto.When the object is eligible for finalization, the garbage collector runs the Finalize method of the object.

Liberação explícita de recursosExplicit release of resources

Se seu aplicativo estiver usando um recurso externo caro, também será recomendável fornecer uma maneira de liberar explicitamente o recurso antes que o coletor de lixo libere o objeto.If your application is using an expensive external resource, we also recommend that you provide a way to explicitly release the resource before the garbage collector frees the object. Você faz isso implementando um método Dispose da interface IDisposable que executa a limpeza necessária para o objeto.You do this by implementing a Dispose method from the IDisposable interface that performs the necessary cleanup for the object. Isso pode melhorar consideravelmente o desempenho do aplicativo.This can considerably improve the performance of the application. Mesmo com esse controle explícito sobre os recursos, o finalizador se tornará uma proteção usada para limpar os recursos se a chamada para o método Dispose falhar.Even with this explicit control over resources, the finalizer becomes a safeguard to clean up resources if the call to the Dispose method failed.

Para obter mais detalhes sobre limpeza de recursos, consulte os seguintes tópicos:For more details about cleaning up resources, see the following topics:

ExemploExample

O exemplo a seguir cria três classes que compõem uma cadeia de herança.The following example creates three classes that make a chain of inheritance. A classe First é a classe base, Second é derivado de First e Third é derivado de Second.The class First is the base class, Second is derived from First, and Third is derived from Second. Todas as três têm finalizadores.All three have finalizers. Em Main, uma instância da classe mais derivada é criada.In Main, an instance of the most-derived class is created. Quando o programa for executado, observe que os finalizadores das três classes são chamados automaticamente e em ordem, do mais derivado para o menos derivado.When the program runs, notice that the finalizers for the three classes are called automatically, and in order, from the most-derived to the least-derived.

class First
{
    ~First()
    {
        System.Diagnostics.Trace.WriteLine("First's destructor is called.");
    }
}

class Second : First
{
    ~Second()
    {
        System.Diagnostics.Trace.WriteLine("Second's destructor is called.");
    }
}

class Third : Second
{
    ~Third()
    {
        System.Diagnostics.Trace.WriteLine("Third's destructor is called.");
    }
}

class TestDestructors
{
    static void Main()
    {
        Third t = new Third();
    }

}
/* Output (to VS Output Window):
    Third's destructor is called.
    Second's destructor is called.
    First's destructor is called.
*/

Especificação da linguagem C#C# language specification

Para obter mais informações, confira a seção Destruidores na Especificação da linguagem C#.For more information, see the Destructors section of the C# language specification.

Consulte tambémSee also