Ce sont quelques lignes directrices pour quand il n'est pas nécessaire de vérifier pour une valeur nulle?
Beaucoup de l'héritage de code j'ai travaillé à partir de la fin a null-contrôles ad nauseam. Null contrôles sur trivial fonctions, null contrôles sur les appels d'API que l'état de non-null renvoie, etc. Dans certains cas, le null-vérifications sont raisonnables, mais dans de nombreux endroits, un nul n'est pas une attente raisonnable.
J'ai entendu un certain nombre d'arguments allant de "Vous ne pouvez pas faire confiance à d'autres code" à "TOUJOURS programme, sur la défensive" à "Jusqu'à ce que la langue des garanties moi une valeur non nulle, je suis toujours à la va vérifier." J'ai certainement d'accord avec bon nombre de ces principes jusqu'à un certain point, mais j'ai trouvé excessif null-vérification de la cause d'autres problèmes qui, généralement, contreviennent à ces principes. Est tenace null vérifier vraiment la peine?
Souvent, j'ai observé les codes avec un excès de nulle vérifier réellement être de moins bonne qualité, pas de qualité supérieure. Une grande partie du code semble être tellement concentré sur null-vérifie que le développeur a perdu de vue les autres qualités importantes, telles que la lisibilité, de l'exactitude, ou la gestion des exceptions. En particulier, je vois beaucoup de code ignorer les std::bad_alloc exception, mais faire un null-case sur un new
.
En C++, je comprends dans une certaine mesure, le comportement imprévisible de déréférencement d'un pointeur null; null déréférencement est traitée avec plus de grâce en Java, C#, Python, etc. Ai-je vu de mauvaise exemples de vigilance null-la vérification ou l'est-il vraiment quelque chose à cela?
Cette question est destinée à être la langue agnostique, mais je m'intéresse principalement en C++, Java et C#.
Quelques exemples de null-vérification que j'ai vu qui semblent être excessive sont les suivants:
Cet exemple semble être de comptabilité pour les non-standard compilateurs C++ spec dit l'échec d'une nouvelle déclenche une exception. Sauf si vous explicitement soutenir non-conforme compilateurs, est-il logique? Cela fait-il de tout sens dans une langue comme le Java ou le C# (ou même en C++/CLR)?
try {
MyObject* obj = new MyObject();
if(obj!=NULL) {
//do something
} else {
//??? most code I see has log-it and move on
//or it repeats what's in the exception handler
}
} catch(std::bad_alloc) {
//Do something? normally--this code is wrong as it allocates
//more memory and will likely fail, such as writing to a log file.
}
Un autre exemple est lorsque l'on travaille sur le code interne. En particulier, si c'est une petite équipe qui peuvent définir leurs propres pratiques en matière de développement, ce qui semble inutile. Sur certains projets ou code hérité de confiance de la documentation ne peut pas être raisonnable... mais pour le nouveau code que vous ou votre équipe de contrôle, est-ce vraiment nécessaire?
Si une méthode, que vous pouvez voir et peut mettre à jour (ou peut crier au développeur qui est responsable) a conclu un contrat, est-il encore nécessaire de vérifier les valeurs null?
//X is non-negative.
//Returns an object or throws exception.
MyObject* create(int x) {
if(x<0) throw;
return new MyObject();
}
try {
MyObject* x = create(unknownVar);
if(x!=null) {
//is this null check really necessary?
}
} catch {
//do something
}
Lors de l'élaboration d'un privé ou autre fonction interne, est-il vraiment nécessaire de traiter explicitement une valeur null lorsque le contrat prévoit des valeurs non nulles seulement? Pourquoi un null-check-être préférable à une assertion?
(évidemment, sur votre API publique, null vérifications sont indispensables; il est considéré comme impoli de crier à vos utilisateurs de manière incorrecte à l'aide de l'API)
//Internal use only--non-public, not part of public API
//input must be non-null.
//returns non-negative value, or -1 if failed
int ParseType(String input) {
if(input==null) return -1;
//do something magic
return value;
}
Par rapport à:
//Internal use only--non-public, not part of public API
//input must be non-null.
//returns non-negative value
int ParseType(String input) {
assert(input!=null : "Input must be non-null.");
//do something magic
return value;
}