Finalizzatori (Guida per programmatori C#)Finalizers (C# Programming Guide)

I finalizzatori (detti anche distruttori) vengono usati per eseguire operazioni di pulizia finale eventualmente necessarie quando un'istanza di classe viene raccolta da Garbage Collector.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.

CommentiRemarks

  • I finalizzatori non possono essere definiti negli struct.Finalizers cannot be defined in structs. Vengono usati solo con le classi.They are only used with classes.

  • Una classe può avere un solo finalizzatore.A class can only have one finalizer.

  • I finalizzatori non possono essere ereditati e non è possibile eseguirne l'overload.Finalizers cannot be inherited or overloaded.

  • I finalizzatori non possono essere chiamati.Finalizers cannot be called. Vengono richiamati automaticamente.They are invoked automatically.

  • Un finalizzatore non accetta modificatori e non ha parametri.A finalizer does not take modifiers or have parameters.

Ad esempio, di seguito è riportata la dichiarazione di un finalizzatore per la classe Car.For example, the following is a declaration of a finalizer for the Car class.

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

Un finalizzatore può anche essere implementato come definizione di corpo dell'espressione, come illustrato nell'esempio seguente.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.");
}

Il finalizzatore chiama implicitamente Finalize per la classe di base dell'oggetto.The finalizer implicitly calls Finalize on the base class of the object. Di conseguenza, una chiamata a un finalizzatore viene convertita implicitamente nel codice seguente:Therefore, a call to a finalizer is implicitly translated to the following code:

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

Questo progetto significa che il Finalize metodo viene chiamato in modo ricorsivo per tutte le istanze nella catena di ereditarietà, dal più derivato al meno derivato.This design means that the Finalize method is called recursively for all instances in the inheritance chain, from the most-derived to the least-derived.

Nota

I finalizzatori vuoti non devono essere usati.Empty finalizers should not be used. Quando una classe contiene un finalizzatore, viene creata una voce nella coda Finalize.When a class contains a finalizer, an entry is created in the Finalize queue. Quando si chiama il finalizzatore, viene richiamato Garbage Collector per elaborare la coda.When the finalizer is called, the garbage collector is invoked to process the queue. Se il finalizzatore è vuoto, si verifica semplicemente un calo di prestazioni.An empty finalizer just causes a needless loss of performance.

Il programmatore non ha alcun controllo sul momento in cui viene chiamato il finalizzatore; il Garbage Collector decide quando chiamarlo.The programmer has no control over when the finalizer is called; the garbage collector decides when to call it. Il Garbage Collector controlla gli oggetti che non vengono più usati dall'applicazione e,The garbage collector checks for objects that are no longer being used by the application. se considera un oggetto idoneo per la finalizzazione, chiama il finalizzatore (se presente) e recupera la memoria usata per archiviare l'oggetto.If it considers an object eligible for finalization, it calls the finalizer (if any) and reclaims the memory used to store the object.

Nelle applicazioni .NET Framework (ma non nelle applicazioni .NET Core) i finalizzatori vengono chiamati anche alla chiusura del programma.In .NET Framework applications (but not in .NET Core applications), finalizers are also called when the program exits.

È possibile forzare la Garbage Collection chiamando Collect , ma nella maggior parte dei casi, questa chiamata deve essere evitata perché potrebbe creare problemi di prestazioni.It's possible to force garbage collection by calling Collect, but most of the time, this call should be avoided because it may create performance issues.

Uso di finalizzatori per liberare risorseUsing finalizers to release resources

In generale, in C# non è richiesto il maggior livello di gestione della memoria da parte dello sviluppatore come linguaggi che non hanno come destinazione un runtime con Garbage Collection.In general, C# does not require as much memory management on the part of the developer as languages that don't target a runtime with garbage collection. Ciò è dovuto al fatto che .NET Garbage Collector gestisce in modo implicito l'allocazione e il rilascio di memoria per gli oggetti.This is because the .NET garbage collector implicitly manages the allocation and release of memory for your objects. Tuttavia, quando l'applicazione incapsula risorse non gestite, ad esempio Windows, file e connessioni di rete, è necessario usare i finalizzatori per liberare tali risorse.However, when your application encapsulates unmanaged resources, such as windows, files, and network connections, you should use finalizers to free those resources. Quando l'oggetto è idoneo per la finalizzazione, il Garbage Collector esegue il metodo Finalize dell'oggetto.When the object is eligible for finalization, the garbage collector runs the Finalize method of the object.

Rilascio esplicito di risorseExplicit release of resources

Se l'applicazione usa una risorsa esterna che consuma molta memoria, è consigliabile specificare un modo per rilasciare la risorsa in modo esplicito prima che il Garbage Collector renda disponibile l'oggetto.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. Per rilasciare la risorsa, implementare un Dispose metodo dall' IDisposable interfaccia che esegue la pulizia necessaria per l'oggetto.To release the resource, implement a Dispose method from the IDisposable interface that performs the necessary cleanup for the object. Questo consente di migliorare notevolmente le prestazioni dell'applicazione.This can considerably improve the performance of the application. Anche con questo controllo esplicito sulle risorse, il finalizzatore diventa una protezione per la pulizia delle risorse se la chiamata al Dispose metodo ha esito negativo.Even with this explicit control over resources, the finalizer becomes a safeguard to clean up resources if the call to the Dispose method fails.

Per ulteriori informazioni sulla pulizia delle risorse, vedere gli articoli seguenti:For more information about cleaning up resources, see the following articles:

EsempioExample

L'esempio seguente crea tre classi che costituiscono una catena di ereditarietà.The following example creates three classes that make a chain of inheritance. La classe First è la classe base, Second è derivata da First e Third è derivata da Second.The class First is the base class, Second is derived from First, and Third is derived from Second. Tutte e tre hanno finalizzatori.All three have finalizers. In Main viene creata un'istanza della classe più derivata.In Main, an instance of the most-derived class is created. Durante l'esecuzione del programma, si noti che i finalizzatori delle tre classi vengono chiamati automaticamente e in ordine, dalla classe più derivata alla meno derivata.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 finalizer is called.");
    }
}

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

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

class TestDestructors
{
    static void Main()
    {
        Third t = new Third();
    }
}
/* Output (to VS Output Window):
    Third's finalizer is called.
    Second's finalizer is called.
    First's finalizer is called.
*/

Specifiche del linguaggio C#C# language specification

Per altre informazioni, vedere la sezione Distruttori della specifica del linguaggio C#.For more information, see the Destructors section of the C# language specification.

Vedi ancheSee also