70 votes

Pourquoi NullReferenceException ne contient-il pas d'informations sur ce qui est null?

Quelle est la décision de conception derrière NullReferenceException qui ne contient aucune information spécifique à l'exécution, à l'exception des données de classe de base (comme un stacktrace)? Et existe-t-il une extension pour Visual Studio qui peut vous dire immédiatement quelle partie d'une expression était nulle?

70voto

Hans Passant Points 475940

Une NRE est un très faible niveau d'exception. C'est un matériel d'exception (un 'piège') généré par le processeur quand il est demandé de lire les données à partir d'une adresse inférieure à 64 ko. Cette région de l'espace de mémoire virtuelle est toujours non cartographiées, spécifiquement pour piéger pointeur de bugs. Il commence comme un AccessViolation et devient NRE par le CLR, quand l'adresse est à moins de 0x00010000. À ce point, il y a très peu de contexte pour l'exception, tout ce qui est connu, c'est l'adresse de la machine du code d'instruction qui a causé le piège.

Le Reverse-engineering de la machine du code d'instruction de l'adresse de retour à une variable nommée dans votre programme n'est pas possible. Il est important que cela fonctionne de cette façon, une gigue aurait pour générer très inefficace code autrement. Tout ce qui peut être raisonnablement faire est de récupérer le code source du numéro de ligne. Qui exige que les informations de débogage (un .apb) qui contient le numéro de la ligne info. Le CLR sait lire l' .fichier pdb et l'utilise pour générer l'exception de la trace de la pile. Cependant, c'est encore souvent imprécise en raison des optimisations effectuées par l'équipe de l'optimiseur, il se déplace code de autour de. Vous obtiendrez seulement une garantie de match pour la version Debug. La raison pour laquelle l'APB pour la version Release ne contient pas de numéro de ligne de source d'info. Vous pouvez changer cela.

Ce problème a une solution très simple. Vérifier la valeur null vous-même et de générer votre propre exception avant de laisser le moteur d'exécution le faire. Le test n'est pas très cher, moins d'une nanoseconde.

26voto

Martin Buberl Points 14573

Vous pouvez configurer Visual Studio pour effectuer une coupure immédiate sur Throw pour NullReferenceException et non en premier au bloc catch.

  • Déboguer
  • Exceptions
  • Langue commune
  • Système d'exceptions d'exécution
  • System.NullReferenceException (cochez la case)

Ensuite, vous aurez une pause dans la ligne qui a causé le NullReferenceException .

5voto

Kirk Woll Points 34601

Il n’existe aucun moyen trivial de déterminer ce qui était nul à l’exécution - les informations nécessaires devraient être décompilées et déduites à partir de l’IL, qui est suffisamment bas pour que tout ce qu’on sait, c’est que "l’élément situé en haut de la pile est nul". "mais pas comment cet article est arrivé là.

(Et je ne connais pas une telle extension, mais ce serait une belle amélioration du débogueur )

4voto

Euro Micelli Points 12845

NullReferenceException est renvoyé par le moteur d'exécution, pas par la langue. Le moteur d'exécution ne sait pas où la référence est venue; il sait simplement qu'une instruction a essayé d'utiliser une référence nulle.

En fait, l'exception est "probablement" le résultat d'une exception SEH de type "violation d'accès invalide" de Windows native, interceptée par le moteur d'exécution et traduite en exception IL ("probablement": je n'ai pas vérifié si c'était le cas, mais je pense que la manière la plus performante de JIT le code).

3voto

Victor Haydin Points 2311

Toutes les informations sur votre code ne sont pas disponibles au moment de l'exécution. Par exemple, les noms de variables locales ne sont pas disponibles. Donc, il est impossible de lancer une exception avec un message comme "La variable locale myObj est null, mais son membre a été appelé". De plus, il existe de nombreux objets non écrits par l'utilisateur au moment de l'exécution (par exemple, des classes, générés pour des fermetures / des types anonymes / des itérateurs, etc.) qui pourraient également être une source d'exceptions null-ref.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X