Que signifie le tilde avant un nom de fonction en C #?

165

Je regarde du code et il contient cette déclaration:

~ConnectionManager()
{
    Dispose(false);
}

La classe implémente l' IDisposableinterface, mais je ne sais pas si cela fait partie de cela le tilde (~) est utilisé.

Keith Sirmons
la source

Réponses:

214

~ est le destructeur

  1. Les destructeurs sont appelés automatiquement et ne peuvent pas être invoqués explicitement.
  2. Les destructeurs ne peuvent pas être surchargés. Ainsi, une classe peut avoir, au plus, un destructeur.
  3. Les destructeurs ne sont pas hérités. Ainsi, une classe n'a pas d'autre destructeur que celui qui peut y être déclaré.
  4. Les destructeurs ne peuvent pas être utilisés avec les structures. Ils ne sont utilisés qu'avec les classes. Une instance devient éligible à la destruction lorsqu'il n'est plus possible pour aucun code d'utiliser l'instance.
  5. L'exécution du destructeur pour l'instance peut avoir lieu à tout moment après que l'instance est éligible à la destruction.
  6. Lorsqu'une instance est détruite, les destructeurs de sa chaîne d'héritage sont appelés, dans l'ordre, du plus dérivé au moins dérivé.

Finaliser

En C #, la méthode Finalize effectue les opérations qu'un destructeur C ++ standard ferait. En C #, vous ne le nommez pas Finalize - vous utilisez la syntaxe du destructeur C ++ qui consiste à placer un symbole tilde (~) avant le nom de la classe.

Disposer

Il est préférable de disposer des objets dans une méthode Close()ou Dispose()qui peut être appelée explicitement par l'utilisateur de la classe. Finalize (destructor) sont appelés par le GC.

L' interface IDisposable indique au monde que votre classe conserve les ressources qui doivent être supprimées et fournit aux utilisateurs un moyen de les libérer. Si vous devez implémenter un finaliseur dans votre classe, votre méthode Dispose doit utiliser la GC.SuppressFinalize()méthode pour garantir que la finalisation de votre instance est supprimée.

Quoi utiliser?

Il n'est pas légal d'appeler un destructeur explicitement. Votre destructeur sera appelé par le garbage collector. Si vous gérez de précieuses ressources non gérées (telles que des descripteurs de fichiers) que vous souhaitez fermer et éliminer le plus rapidement possible, vous devez implémenter l'interface IDisposable.

Patrick Desjardins
la source
3
Je ne sais pas comment c'était dans le passé. Mais maintenant, les destructeurs sont hérités. Consultez ce lien pour plus d'informations (consultez l'exemple à la fin): msdn.microsoft.com/en-us/library/66x5fx1b.aspx
RononDex
1
@RononDex le point 3 de la page même vers laquelle vous liez indique que "les finaliseurs ne peuvent pas être hérités" , ce qui contredit votre commentaire. Certes, tout est un peu déroutant car bien qu'elles ne puissent pas être héritées, "la Finalizeméthode est appelée récursivement pour toutes les instances de la chaîne d'héritage, de la plus dérivée à la moins dérivée" . Notez que ce n'est pas le même comportement que celui des destructeurs héritables.
Mark Amery
@MarkAmery ah je vois, donc fondamentalement, ils sont appelés dans l'ordre inverse par rapport à quelque chose qui est hérité?
RononDex
45

Ceci est un finaliseur . Pour être honnête, vous devriez très rarement avoir besoin d'écrire un finaliseur. Vous n'avez vraiment besoin d'en écrire qu'un si:

  • Vous avez un accès direct à une ressource non gérée (par exemple via un IntPtr) et vous ne pouvez pas l'utiliser, SafeHandlece qui facilite les choses
  • Vous implémentez IDisposabledans une classe qui n'est pas scellée. (Ma préférence est de sceller les classes à moins qu'elles ne soient conçues pour l'héritage.) Un finaliseur fait partie du modèle de Dispose canonique dans de tels cas.
Jon Skeet
la source
9

Il est utilisé pour indiquer le destructeur de la classe.

torial
la source
12
Ils sont tous les deux corrects, selon la spécification C # que vous lisez. Le MS le plus récent (C # 3.0 unifié) les désigne comme des destructeurs (par exemple, section 10.13) mais la spécification ECMA les désigne comme des finaliseurs.
Jon Skeet
@ 1800INFORMATION: L' élément syntaxique est proprement appelé un destructeur. Si une classe a un destructeur, un compilateur C # générera automatiquement un finaliseur qui comprend un try/finallybloc généralement inutile qui garantit que la Finalizeméthode parente est appelée. La plupart des choses qui sont vraies pour les destructeurs sont vraies pour les finaliseurs, et vice versa, mais les mots signifient des choses légèrement différentes.
supercat
4

Identique au C ++, c'est le destructeur; cependant en C # vous ne l'appelez pas explicitement, il est invoqué lorsque l'objet est collecté.

Santiago Palladino
la source
3

Voir Destructors (Guide de programmation C #) . Sachez cependant que, contrairement au C ++, le programmeur n'a aucun contrôle sur le moment où le destructeur est appelé car cela est déterminé par le garbage collector.

Jeff Stong
la source
1

~ représente généralement un déconstructeur. qui est exécuté juste avant la mort d'un objet.

Voici une description des déconstructeurs C # que j'ai trouvés

Stephenbayer
la source
4
le terme correct doit être destructeur / finaliseur et non déconstructeur. Deconstructor signifie une syntaxe pour déconstruire un constructeur.
Eriawan Kusumawardhono