Nous lançons un système et nous recevons parfois la fameuse exception NullReferenceException
avec le message Object reference not set to an instance of an object
.
Cependant, dans une méthode où nous avons presque 20 objets, le fait d'avoir un journal indiquant qu'un objet est nul est vraiment inutile. C'est comme vous dire, lorsque vous êtes l'agent de sécurité d'un séminaire, qu'un homme sur 100 participants est un terroriste. C'est vraiment d'aucune utilité pour vous. Vous devriez obtenir plus d'informations si vous voulez détecter quel homme est l'homme menaçant.
De même, si nous voulons supprimer le bogue, nous devons savoir quel objet est null.
Maintenant, quelque chose a obsédé mon esprit pendant plusieurs mois, à savoir:
Pourquoi .NET ne nous donne-t-il pas le nom, ou du moins le type de la référence d'objet, qui est null? . Ne peut-il pas comprendre le type de réflexion ou de toute autre source?
En outre, quelles sont les meilleures pratiques pour comprendre quel objet est nul? Devrions-nous toujours tester manuellement la nullité des objets dans ces contextes et enregistrer le résultat? Y a-t-il un meilleur moyen?
Mise à jour:
l'exception The system cannot find the file specified
a la même nature. Vous ne pouvez pas trouver quel fichier, tant que vous n'avez pas joint le processus et débogué. Je suppose que ces types d'exceptions peuvent devenir plus intelligents. Ne serait-il pas préférable que .NET puisse nous dire c:\temp.txt doesn't exist.
au lieu de ce message général? En tant que développeur, je vote oui.
la source
new
pour créer des instances d'une classe. Quand un tel indice aide-t-il vraiment?Réponses:
Le
NullReferenceException
fondamentalement vous dit: vous le faites mal. Ni plus ni moins. Ce n'est pas un outil de débogage à part entière, au contraire. Dans ce cas, je dirais que vous le faites mal à la fois parce queJe suis un grand partisan de tout vérifier avant que les choses ne commencent à tourner mal et de fournir de bonnes informations au développeur. En bref: écrivez des chèques en utilisant
ArgumentNullException
et et aimez et écrivez le nom vous-même. Voici un exemple:Vous pouvez aussi regarder dans les contrats de code , ça a des bizarreries mais ça marche plutôt bien et vous évite de taper.
la source
I only say that checking every object to get sure that it's not null, is not a good method
Sérieusement. C'est la meilleure méthode. Et pas seulement null, vérifiez chaque argument pour des valeurs raisonnables. Plus tôt vous attrapez les erreurs, plus il est facile de trouver la cause. Vous ne voulez pas avoir à revenir en arrière sur plusieurs niveaux dans la trace de la pile pour trouver l'appel à l'origine.Cela devrait montrer exactement ce que vous essayez d'appeler. C'est comme dire "Il y a un problème. Vous devez le résoudre. Je sais ce que c'est. Je ne vais pas vous le dire. Vous allez le découvrir." Un peu comme la moitié des réponses à ce débordement de pile, ironiquement.
Alors, quelle serait l'utilité, par exemple, si vous obteniez ceci ...
...? Vous devez entrer dans le code, le parcourir et vous rendre compte que vous essayez d'appeler,
null
c'est bien, mais pourquoi ne pas simplement nous donner un petit coup de pouce?Je conviens qu'il est généralement utile de parcourir le code pour trouver la réponse (car vous en saurez probablement plus), mais souvent, beaucoup de temps et de frustration seraient économisés si le
NullReferenceException
texte ressemblait davantage à l'exemple ci-dessus.Juste dire.
la source
KeyNotFoundException
beaucoup d'autres ennuis ...Votre journal doit inclure une trace de la pile - elle vous indique généralement quelle ligne de la méthode pose problème. Vous devrez peut-être obliger votre version à inclure les symboles PDB pour avoir une idée de la ligne sur laquelle l'erreur se produit.
Certes, cela ne vous aidera pas dans ce cas:
Le principe dit de ne pas demander peut aider à éviter un tel code.
En ce qui concerne la raison pour laquelle les informations ne sont pas incluses, je ne suis pas sûr - je suppose qu'au moins dans une version de débogage, s'ils le voulaient vraiment, ils pourraient le comprendre. Effectuer un vidage sur incident et une ouverture dans WinDBG peut aider.
la source
Des exceptions ont été créées en tant qu'outil pour signaler des conditions exceptionnelles non fatales tout au long de la chaîne d'appels. Autrement dit, ils ne sont pas conçus comme un outil de débogage.
Si une exception null-pointeur était un outil de débogage, il abandonnerait l'exécution du programme sur-le-champ, permettant à un débogueur de se connecter, en le pointant directement sur la ligne incriminée. Cela donnerait au programmeur toutes les informations de contexte disponibles. (Ce qui est à peu près ce qu'un Segfault dû à un pointeur nul, fait en C, bien qu'un peu grossièrement.)
Cependant, l'exception null-pointeur est conçue comme une condition d'exécution valide pouvant être levée et interceptée dans le flux de programme normal. Par conséquent, les considérations de performance doivent être prises en compte. Et toute personnalisation du message d'exception nécessite la création, la concaténation et la destruction des objets chaîne au moment de l'exécution. En tant que tel, un message statique est incontestablement plus rapide.
Je ne dis pas que le runtime ne pourrait pas être programmé de manière à donner le nom de la référence incriminante. Cela pourrait être fait. Cela ferait juste des exceptions encore plus lentement qu'elles ne le sont. Si quelqu'un le tenait suffisamment à cœur, une telle fonctionnalité pourrait même être commutée pour ne pas ralentir le code de production, mais permettre un débogage plus facile. mais pour une raison quelconque, personne ne semble s’être assez intéressé.
la source
Cromulent a touché le clou, je pense, cependant, il y a aussi le point évident que si vous obtenez une
NullReferenceException
variable non initialisée. L'argument selon lequel environ 20 objets sont passés dans une méthode ne peut pas être considéré comme une atténuation: en tant que créateur d'un bloc de code, vous devez être responsable de son fonctionnement, ce qui inclut sa conformité au reste d'une base de code, comme ainsi que l'utilisation correcte et correcte des variables, etc.c’est pénible, fastidieux et parfois ennuyeux, mais les récompenses finales en valent la peine: bien souvent, j’ai dû parcourir des fichiers journaux pesant plusieurs giga-octets et qui sont presque toujours utiles. Cependant, avant d’arriver à cette étape, le débogueur peut vous aider et, avant cette étape, une bonne planification vous épargnera beaucoup de peine (et je ne veux pas dire une approche entièrement conçue de votre solution de code: des croquis simples et quelques notes peuvent et vont vous aider. être meilleur que rien).
En ce qui concerne
Object reference not set to an instance of an object
le code ne peut pas deviner les valeurs que nous pouvons aimer: c’est notre travail de programmeurs et cela signifie simplement que vous avez passé une variable non initialisée dans.la source
Apprenez à utiliser le débogueur. C'est exactement le genre de chose pour laquelle il est conçu. Définissez un point de rupture sur la méthode en question et c'est parti.
Parcourez simplement votre code et voyez exactement quelles sont les valeurs de toutes vos variables à certains moments.
Edit: Franchement, je suis choqué que personne d’autre n’a encore mentionné l’utilisation du débogueur.
la source
Si vous voulez aller avec la réponse de @ stijn et mettre des contrôles nuls dans votre code, cet extrait de code devrait vous aider. Voici quelques informations sur les extraits de code . Une fois cette configuration configurée, il vous suffit de taper
argnull
, d'appuyer deux fois sur la touche tabulation, puis de remplir le vide.la source
nameof
votre extraitthrow new ArgumentNullException(nameof($argument$))
qui présente les avantages de ne pas inclure les constantes magiques, d'être vérifié par le compilateur, et de mieux fonctionner avec les outils de refactoring