web-dev-qa-db-fra.com

C #: les variables d'objet doivent-elles être affectées à null?

En C #, est-il nécessaire d’affecter une variable d’objet à null si vous avez fini de l’utiliser, même si sa portée sortira de toute façon?

43
Craig Johnston

Non, et cela pourrait en fait être dangereux et sujet à des bogues (envisagez la possibilité que quelqu'un essaye de l'utiliser ultérieurement, sans se rendre compte qu'il avait été mis à null) Définissez quelque chose sur null s'il existe une raison logique de le définir sur null.

37
Daniel DiPaolo

Ce qui compte le plus à l’OMI, c’est d’appeler Dispose sur les objets qui implémentent IDisposable.

Indépendamment de cela, l’affectation de valeurs nulles à des variables de référence signifie simplement que vous indiquez explicitement la fin de l’étendue - la plupart du temps, ses quelques instructions à l’avance (par exemple, les variables locales dans le corps de la méthode) - avec l’époque des optimisations du compilateur/JIT, Il est tout à fait possible que l'exécution fasse la même chose, donc vous n'en tirez absolument rien. Dans de rares cas, tels que les variables statiques, etc. (dont la portée est au niveau de l'application), vous devez affecter la valeur null à la variable si vous avez fini de l'utiliser, de sorte que l'objet soit récupéré.

26
VinayC

Devriez-vous éteindre votre voiture avant de la pousser vers le lac?
Non. C'est une erreur commune, mais cela ne fait aucune différence. Vous ne définissez pas l'objet objet sur la valeur null, mais sur une référence , l'objet est toujours en mémoire et doit toujours être collecté par le garbage collector. 

23
Kobi

La plupart de ces réponses ont la bonne réponse, mais pour les mauvaises raisons.

S'il s'agit d'une variable locale, la variable tombera de la pile à la fin de la méthode et donc l'objet référencé aura une référence de moins. Si cette variable était la seule référence à l'objet, celui-ci est disponible pour GC.

Si vous définissez la variable sur null (et que beaucoup de ceux qui le font ont appris à le faire à la fin de la méthode), vous pourriez alors prolonger le délai de conservation de l'objet, car le CLR croira qu'il ne peut pas être collecté jusqu'à la fin de la méthode car il voit une référence de code à l'objet en bas. Toutefois, si vous omettez le paramètre null, le CLR peut déterminer qu'il ne reste plus d'appels pour l'objet après un certain point dans votre code et que, même si la méthode n'est pas encore terminée, le GC peut collecter l'objet.

17
user1739635

Assigner à null est généralement une mauvaise idée:

  1. Conceptuellement, c'est inutile.
  2. Avec de nombreuses variables, vous pouvez avoir suffisamment d’assignations supplémentaires pour annuler la taille de la méthode. Plus le code source de quelque chose est long, plus l'effort mental nécessaire pour le lire (même s'il s'agit en grande partie de choses pouvant être filtrées) est important, et plus il est facile de repérer un bogue. Rendez le code plus bavard que nécessaire uniquement lorsque cela le rend plus compréhensible.
  3. Il est possible que votre affectation nulle ne soit pas optimisée. Dans ce cas, il est possible que le code compilé n'effectue pas la véritable désallocation tant qu'il n'atteint pas cette affectation nulle, alors que dans la plupart des cas, une fois que la variable ne fera rien d'autre que de tomber hors de portée peut être désalloué. Vous pouvez donc avoir un impact très mineur sur les performances.

La seule fois où j'attribuerais quelque chose à null pour "effacer" une variable qui ne sera plus utilisée, plutôt que parce que null est en fait une valeur que je veux explicitement assigner, se trouve dans l'un des deux cas suivants:

  1. Il fait partie d'un objet susceptible d'avoir une longue vie, ne sera plus utilisé par cet objet et est de taille considérable. Ici, assigner à null est une optimisation.
  2. Il est membre d'un objet potentiellement longévif, ne sera plus utilisé par cet objet et a donc été disposé à libérer ses ressources. Dans ce cas, l’assignation à null est une question de sécurité car il peut être plus facile de trouver un cas où l’on utilise accidentellement un objet nul que l’utilisation accidentelle d’un objet supprimé.

Aucun de ces cas ne s'applique aux variables locales, mais uniquement aux membres, et les deux sont rares.

11
Jon Hanna

Non. Quand il s’agit de variables locales, qu’il y ait une référence à l’objet ou non, l’important est de savoir si la référence sera utilisée ou non.

Ajouter une affectation null supplémentaire dans le code ne nuit pas beaucoup aux performances et n'affecte en rien la gestion de la mémoire, mais ajoute au code des instructions non motivées qui le rendent moins lisible.

Le ramasse-miettes sait à quel moment la référence est utilisée pour la dernière fois dans le code. Il peut donc collecter l'objet dès qu'il n'est plus nécessaire.

Exemple:

{
  // Create an object
  StringBuilder b = new StringBuilder();
  b.Append("asdf");
  // Here is the last use of the object:
  string x = b.ToString();
  // From this point the object can be collected whenever the GC feels like it
  // If you assign a null reference to the variable here is irrelevant
  b = null;
}
4
Guffa

J'aimerais juste ajouter que, autant que je sache, il ne s'agissait que d'un modèle valide pour une version ponctuelle de Visual Basic, et même que - était quelque peu discutable. (IIRC c'était seulement pour les objets DAO.)

0
Mark Hurd