Finaliseurs (Guide de programmation C#)Finalizers (C# Programming Guide)

Les finaliseurs (également appelés destructeurs) servent à effectuer les derniers nettoyages nécessaires lorsqu’une instance de classe est collectée par le récupérateur de mémoire.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.

RemarquesRemarks

  • Les finaliseurs ne peuvent pas être définis dans des structs.Finalizers cannot be defined in structs. Ils sont utilisés uniquement avec les classes.They are only used with classes.

  • Une classe ne peut avoir qu’un seul finaliseur.A class can only have one finalizer.

  • Les finaliseurs ne peuvent pas être hérités ou surchargés.Finalizers cannot be inherited or overloaded.

  • Les finaliseurs ne peuvent pas être appelés.Finalizers cannot be called. Ils sont appelés automatiquement.They are invoked automatically.

  • Un finaliseur ne prend pas de modificateur et n’a pas de paramètre.A finalizer does not take modifiers or have parameters.

Par exemple, voici une déclaration de finaliseur pour la classe Car.For example, the following is a declaration of a finalizer for the Car class.

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

Un finaliseur peut aussi être implémenté en tant que définition de corps d’expression, comme l’illustre l’exemple suivant.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.");
}

Le finaliseur appelle implicitement Finalize sur la classe de base de l’objet.The finalizer implicitly calls Finalize on the base class of the object. Ainsi, un appel à un finaliseur est traduit implicitement en ce code :Therefore, a call to a finalizer is implicitly translated to the following code:

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

Cela signifie que la méthode Finalize est appelée de manière récursive pour toutes les instances de la chaîne d’héritage, de la plus dérivée à la moins dérivée.This means that the Finalize method is called recursively for all instances in the inheritance chain, from the most-derived to the least-derived.

Notes

Les finaliseurs vides ne doivent pas être utilisés.Empty finalizers should not be used. Quand une classe contient un finaliseur, une entrée est créée dans la file d’attente Finalize.When a class contains a finalizer, an entry is created in the Finalize queue. Quand le finaliseur est appelé, le récupérateur de mémoire est appelé pour traiter la file d’attente.When the finalizer is called, the garbage collector is invoked to process the queue. Un finaliseur vide entraîne une perte de performances inutile.An empty finalizer just causes a needless loss of performance.

Le programmeur n’a aucun contrôle sur le moment où le finaliseur est appelé, car celui-ci est déterminé par le récupérateur de mémoire.The programmer has no control over when the finalizer is called because this is determined by the garbage collector. Le récupérateur de mémoire recherche les objets qui ne sont plus utilisés par l’application.The garbage collector checks for objects that are no longer being used by the application. S’il considère qu’un objet peut être finalisé, il appelle le finaliseur (s’il y en a un) et libère la mémoire utilisée pour stocker l’objet.If it considers an object eligible for finalization, it calls the finalizer (if any) and reclaims the memory used to store the object.

Dans les applications .NET Framework (mais pas dans les applications .NET Core), les finaliseurs sont également appelés quand le programme se termine.In .NET Framework applications (but not in .NET Core applications), finalizers are also called when the program exits.

Il est possible de forcer le nettoyage de la mémoire en appelant Collect, mais la plupart du temps c’est à éviter car cela peut créer des problèmes de performances.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.

Utiliser des finaliseurs pour libérer des ressourcesUsing finalizers to release resources

En général, C# ne nécessite pas autant de gestion de mémoire que quand vous développez avec un langage qui ne cible pas un runtime avec nettoyage de la mémoire.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. En effet, le récupérateur de mémoire .NET Framework gère implicitement l’allocation et la libération de la mémoire pour vos objets.This is because the .NET Framework garbage collector implicitly manages the allocation and release of memory for your objects. Toutefois, quand votre application encapsule des ressources non managées, telles que des fenêtres, des fichiers et des connexions réseau, vous devez utiliser des finaliseurs pour libérer ces ressources.However, when your application encapsulates unmanaged resources such as windows, files, and network connections, you should use finalizers to free those resources. Quand l’objet peut être finalisé, le récupérateur de mémoire exécute la méthode Finalize de l’objet.When the object is eligible for finalization, the garbage collector runs the Finalize method of the object.

Libération explicite de ressourcesExplicit release of resources

Si votre application utilise une ressource externe coûteuse, nous vous recommandons également de proposer un moyen de libérer explicitement la ressource avant que le récupérateur de mémoire ne libère l’objet.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. Pour cela, vous devez implémenter une méthode Dispose à partir de l’interface IDisposable qui effectue le nettoyage nécessaire pour l’objet.You do this by implementing a Dispose method from the IDisposable interface that performs the necessary cleanup for the object. Cela peut améliorer considérablement les performances de l’application.This can considerably improve the performance of the application. Même avec ce contrôle explicite des ressources, le finaliseur devient un dispositif de protection pour nettoyer les ressources si l’appel à la méthode Dispose a échoué.Even with this explicit control over resources, the finalizer becomes a safeguard to clean up resources if the call to the Dispose method failed.

Pour plus d’informations sur le nettoyage des ressources, consultez les rubriques suivantes :For more details about cleaning up resources, see the following topics:

ExempleExample

L’exemple suivant crée trois classes qui forment une chaîne d’héritage.The following example creates three classes that make a chain of inheritance. La classe First est la classe de base, Second est dérivée de First, et Third est dérivée de Second.The class First is the base class, Second is derived from First, and Third is derived from Second. Toutes trois ont des finaliseurs.All three have finalizers. Dans Main, une instance de la classe la plus dérivée est créée.In Main, an instance of the most-derived class is created. Quand le programme s’exécute, notez que les finaliseurs des trois classes sont appelés automatiquement, et dans l’ordre, de la plus dérivée à la moins dérivée.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.
*/

spécification du langage C#C# language specification

Pour plus d’informations, voir la section Destructeurs de la spécification du langage C#.For more information, see the Destructors section of the C# language specification.

Voir aussiSee also