La différence entre un destructeur et un finaliseur?

s'il vous Plaît Note: Cette question est à propos de la différence de terminologie entre les mots "destructeur" et "finaliseur" et leur utilisation correcte. J'ai simplement fourni des exemples de leur utilisation dans C# et C++/CLI pour démontrer pourquoi je pose la question. Je suis bien conscient de la façon dont il est mis en œuvre à la fois dans C# et dans le CLR, mais je m'interroge sur l'utilisation correcte de la terminologie.


dans le monde entier, les Termes "destructeur" et "finalisateur" semblent être utilisés presque de façon interchangeable, ce que je soupçonne est parce que la spécification C# décrit la fonctionnalité de nettoyage non-déterministe en utilisant le mot "destructeur", tandis que la documentation CLR utilise toujours le mot "finalizer", donc dans les royaumes de C# ils signifient la même chose.

cependant, dans la spécification C++/CLI, il y a une distinction entre les deux. Il permet le nettoyage déterministe et non déterministe, et utilise le terme "destructeur" pour le déterministe la fonctionnalité et "finaliseur" pour les non-déterministe de la fonctionnalité:

Le finaliseur offre non-déterministe de nettoyage. Un finalizer est une fonction de" dernière chance " qui est exécutée pendant le ramassage des ordures, typiquement sur un objet dont le destructeur n'a pas été exécuté.

en outre les descriptions Wikipédia de destructeur et finaliseur indiquent que les destructeurs et les finaliseurs sont des concepts distincts, et soutient L'utilisation des termes par C++/clic spec en ce qui concerne le déterminisme:

Contrairement aux destructeurs, les finalisateurs ne sont pas déterministes. Un destructeur est exécuté lorsque le programme libère explicitement un objet. Un finalizer, par contre, est exécuté lorsque le système interne de collecte des ordures libère l'objet.

les questions:

  • Existe-t-il, du point de vue de l'informatique, une différence clairement définie entre un "destructeur"" et un "finalisateur", ou la terminologie est-elle quelque chose qui ne peut être défini que contextuellement?

  • S'il y a une différence clairement définie, alors pourquoi le C# spec utilise-t-il la "mauvaise" terminologie?

33
demandé sur Greg Beech 2009-12-09 12:40:50

4 réponses

1) y a-t-il une différence bien définie entre "destructeur" et "finalisateur" tel qu'utilisé dans l'industrie ou le milieu universitaire?

Il y a certainement. La différence semble être que les destructeurs sont des méthodes de nettoyage qui sont invoquées de façon déterministe, alors que les finalisateurs courent quand le collecteur d'ordures leur dit de le faire.

2) dans ce cas, le C# spec se trompe -- les finaliseurs sont appelés "destructeurs" en C#. Pourquoi les auteurs de la C# spec obtenir de mal?

je ne sais pas, mais je peux deviner. En fait, j'ai deux suppositions.

Guess #1 est que le 12 mai 1999 il n'y avait pas d'article de wikipedia décrivant clairement la différence subtile entre ces deux concepts. C'est parce que il n'y avait pas de wikipédia. Tu te souviens quand il n'y avait pas de Wikipédia? Age des ténèbres, l'homme. L'erreur aurait pu simplement être une erreur de bonne foi, en croyant que les deux termes étaient identiques.

Diable, pour autant que je sache, les deux termes étaient identique le 12 mai 1999, et la différence dans les définitions n'a évolué que plus tard, car il est devenu évident qu'il y avait un besoin de se disambiguer entre les méthodes de nettoyage impatientes et paresseuses.

Guess #2 est que le 12 Mai 1999, la langue comité de conception souhaité laisser ouverte la possibilité qu'un "destructeur" pourrait être mis en œuvre comme quelque chose autres qu'un outil de finalisation. C'est-à-dire que le "destructeur" a été conçu pour être un concept de langage C# pas nécessairement la carte un-à-un avec le concept .net "finalizer". Lorsque vous concevez un langage en même temps que le cadre sur lequel il se trouve est également conçu, parfois vous voulez vous isoler des changements de conception de dernière minute dans vos sous-systèmes.

La langue du comité de notes pour le 12 Mai 1999, en partie:

Nous allons utiliser le terme "destructeur" pour le membre qui exécute lorsqu'une instance est récupérée. Classe peut avoir les destructeurs; les structures ne peuvent pas. Contrairement au C++, un destructeur ne peut pas être appelé explicitement. La Destruction est non-déterministe – vous ne pouvez pas fiable savoir quand le destructeur va exécuter les, sauf pour dire qu'il s'exécute à certains point après toutes les références à la objet ont été libérés. Le destructeurs dans une chaîne d'héritage sont appelés dans l'ordre, de la plus descendant au moindre descendant. Y est pas nécessaire (et pas moyen) pour la classe dérivée appeler explicitement la base destructeur. Le compilateur C# compile de destructeurs pour l' représentation appropriée de CLR. Pour cette version qui signifie probablement exemple finaliseur qui est distingué dans les métadonnées. CLR may fournir statique finaliseurs dans le l'avenir; nous ne voyons pas de barrière à l' C # utilisant des finaliseurs statiques.

Donc, là, vous savez maintenant tout ce que je sais sur le sujet. Si vous voulez en savoir plus, demandez à Anders la prochaine fois que vous le verrez.

37
répondu Eric Lippert 2009-12-10 15:05:47

à proprement parler C# n'a pas de destructeur (je crois que le C# spec est déroutant sur ce point). Le finalizer de C#ressemble à un destructeur de C++ mais, comme vous le dites, est non-déterministe. C# a déterministe de nettoyage dans la forme IDisposable::Dispose (mais ce n'est pas encore appelé le destructeur).

C++ / CLI a des destructeurs déterministes, qui ressemblent à des destructeurs C++. Au niveau CLI ces cartes sur IDisposable::Dispose() (IDisposable est implémenté pour vous). C++ / CLI a des finalisateurs non déterministes, qui ressemblent à des destructeurs mais utilisent le ! préfixe au lieu du préfixe^.

le fait que C++ / CLI utilise la même syntaxe pour les destructeurs que C# utilise pour les finalisateurs peut être un peu déroutant - mais il correspond mieux à C++, qui a une forte tradition de destruction déterministe.

malheureusement, l'absence de définitions universelles de ces termes signifie que vous devez toujours clarifier ce dont vous parlez. Personnellement j'utilise toujours le mot finaliseur quand on parle du C # concept et Réserve destructeur pour les contextes où cela implique définitivement une destruction déterministe.

[mise à Jour] Depuis mon premier post ici Eric Lippert a posté sa réponse (la réponse acceptée) et suivi avec un blog sur le même. Je suis heureux de voir que nous sommes d'accord :-)

6
répondu philsquared 2010-02-17 19:28:13

je crois "destructeur" est le code C#, et le "finaliseur" est la compilation des CIL de la méthode. Le compilateur C # transforme un destructeur en un finalisateur.

EDIT: Pour être plus verbeux; Le langage C# spécification définit un "destructeur" comme un C# méthode d'instance d'une classe. 'destructor' fait donc partie de la grammaire C# -- Les Destructeurs sont un objet linguistique qui apparaît dans le code source.

un destructeur est un membre qui met en œuvre les actions nécessaires pour détruire un instance d'une classe. Les destructeurs ne peuvent pas avoir de paramètres, ils ne peuvent pas avoir de modificateurs d'accessibilité, et ils ne peuvent pas être invoqués explicitement. Le destructeur d'une instance est invoqué automatiquement lors du ramassage des ordures.

A 'finaliseur" est un terme utilisé dans le Common Language Runtime, par exemple dans les appels à GC.WaitForPendingFinalizers(), et il se réfère à n'importe quel langage .net, pas seulement C#. Tout type de référence. net peut avoir un finalizer. Pour une Classe C# (l'artéfact du code source), le destructeur compile dans la méthode CIL qui est le finaliseur du type CLR.

ou plus succinctement,destructeurfinaliseur code sourceCode machine;)

4
répondu Steve Cooper 2009-12-09 13:28:45

si nous nous en tenons à la définition "déterministe" des destructeurs, alors je dirais que dans .NET les objets n'ont pas de destructeurs à moins d'être explicitement implémentés en utilisant l'interface IDisposable.

3
répondu Konamiman 2009-12-09 09:46:52