web-dev-qa-db-fra.com

Différence entre destructeur, éliminer et finaliser

J'étudie le fonctionnement du ramasse-miettes en c #. Je suis confus quant à l'utilisation des méthodes Destructor, Dispose et Finalize.

Selon mes recherches et mes compréhensions, le fait d’avoir une méthode Destructor dans ma classe indiquera au garbage collector qu’il doit effectuer le garbage collection de la manière indiquée dans la méthode destructor, qui ne peut pas être appelée explicitement sur les instances de la classe.

La méthode Dispose est destinée à permettre à l'utilisateur de contrôler le garbage collection. La méthode Finalize libère les ressources utilisées par la classe, mais pas l'objet lui-même.

Je ne suis pas sûr d'avoir bien compris. S'il vous plaît clarifier les doutes. Tous les autres liens ou guides sont les bienvenus.

61
Victor Mukherjee

Destructor appelle implicitement la méthode Finalize, elles sont techniquement identiques. Dispose est disponible avec les objets qui implémentent l'interface IDisposable.

Vous pouvez voir: Destructors C # - MSDN

Le destructeur appelle implicitement Finalize sur la classe de base de l'objet.

Exemple du même lien:

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

Le code de destructeur est implicitement traduit en code suivant:

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

Votre compréhension pour le destructeur est juste:

De MSDN

Le programmeur n'a aucun contrôle sur le moment où le destructeur est appelé car il est déterminé par le garbage collector . Le garbage collector recherche les objets qui ne sont plus utilisés par l'application. S'il considère qu'un objet peut être détruit, il appelle le destructeur (le cas échéant) et récupère la mémoire utilisée pour stocker l'objet. Les destructeurs sont également appelés à la sortie du programme. Il est possible de forcer la récupération de place en appelant Collect, mais la plupart du temps, cela devrait être évité car cela pourrait créer des problèmes de performances.

54
Habib

En termes C #, un destructeur et un finaliseur sont des concepts fondamentalement interchangeables et doivent être utilisés pour libérer des ressources non gérées lorsqu'un type est collecté, par exemple des descripteurs externes. C'est très rare que vous ayez besoin d'écrire un finaliseur.

Le problème avec cela est que GC n’est pas déterministe, la méthode Dispose() (via IDisposable) permet de prendre en charge déterministe nettoyage. Cela n'a aucun lien avec la récupération de place et permet à l'appelant de libérer les ressources plus tôt . Il est également approprié pour une utilisation avec des ressources gérées (en plus des ressources non gérées), par exemple si vous avez un type qui encapsule (par exemple) une connexion à une base de données, vous voudrez peut-être également supprimer le type pour libérer la connexion.

41
Marc Gravell