Par exemple:
public class Person
{
public Person()
{
}
~Person()
{
}
}
Quand dois-je créer manuellement un destructeur? Quand avez-vous eu besoin de créer un destructeur?
MISE À JOUR: Cette question était l'objet de mon blog en mai 2015 . Merci pour la bonne question! Voir le blog pour une longue liste de mensonges que les gens croient généralement à propos de la finalisation.
Quand dois-je créer manuellement un destructeur?
Presque jamais.
Généralement, on ne crée un destructeur que lorsque votre classe conserve des ressources non gérées coûteuses qui doivent être nettoyées lorsque l'objet disparaît. Il est préférable d’utiliser le motif jetable pour s’assurer que la ressource est nettoyée. Un destructeur est donc essentiellement une assurance que si le consommateur de votre objet oublie de le jeter, la ressource sera toujours nettoyée. (Peut être.)
Si vous créez un destructeur , soyez extrêmement prudent et comprenez le fonctionnement du garbage collector . Les destructeurs sont vraiment étranges :
Presque rien de ce qui est normalement vrai n'est vrai dans un destructeur. Sois vraiment très prudent. Écrire un destructeur correct est très difficile.
Quand avez-vous eu besoin de créer un destructeur?
Lors du test de la partie du compilateur qui gère les destructeurs. Je n'ai jamais eu besoin de le faire dans le code de production. J'écris rarement des objets manipulant des ressources non gérées.
C'est ce qu'on appelle un "finaliseur", et vous ne devriez généralement en créer qu'une pour une classe dont l'état (c'est-à-dire: les champs) inclut des ressources non gérées (c'est-à-dire: les pointeurs vers les handles récupérés via des appels p/invoke). Cependant, dans .NET 2.0 et les versions ultérieures, il existe en fait un meilleur moyen de nettoyer les ressources non gérées: SafeHandle . Compte tenu de cela, vous ne devriez pratiquement plus jamais avoir besoin d’écrire un finaliseur.
Vous n'en aurez besoin que si votre classe gère des ressources non gérées, telles que les descripteurs de fichiers Windows.
Il s’appelle destructeur/finaliseur et est généralement créé lors de l’implémentation du modèle Disposed.
C'est une solution de secours lorsque l'utilisateur de votre classe oublie d'appeler Dispose pour s'assurer que (éventuellement) vos ressources sont libérées, mais vous n'avez aucune garantie quant au moment où le destructeur est appelé.
Dans cette question de débordement de pile , la réponse acceptée montre correctement comment mettre en œuvre le modèle de disposition. Cela n'est nécessaire que si votre classe contient des ressources non gérées que le récupérateur de place ne parvient pas à nettoyer lui-même.
Une bonne pratique consiste à ne pas implémenter de finaliseur sans donner également à l'utilisateur de la classe la possibilité de disposer manuellement de l'objet pour libérer immédiatement les ressources.
Lorsque vous disposez de ressources non gérées et que vous devez vous assurer qu'elles seront nettoyées lorsque votre objet disparaîtra. Un bon exemple serait les objets COM ou les gestionnaires de fichiers.
J'ai utilisé un destructeur (uniquement à des fins de débogage) pour voir si un objet était en train d'être purgé de la mémoire dans le cadre d'une application WPF. Je ne savais pas si le ramasse-miettes était en train de purger réellement l'objet de la mémoire et c'était un bon moyen de vérifier.
Les destructeurs fournissent un moyen implicite de libérer des ressources non managées encapsulées dans votre classe. Ils sont appelés lorsque le GC les utilise et appellent implicitement la méthode Finalize de la classe de base. Si vous utilisez beaucoup de ressources non gérées, il est préférable de fournir un moyen explicite de libérer ces ressources via l'interface IDisposable. Consultez le guide de programmation C #: http://msdn.Microsoft.com/en-us/library/66x5fx1b.aspx