J'ai un morceau de code qui peut être représenté comme:
public class ItemService {
public void DeleteItems(IEnumerable<Item> items)
{
// Save us from possible NullReferenceException below.
if(items == null)
return;
foreach(var item in items)
{
// For the purpose of this example, lets say I have to iterate over them.
// Go to database and delete them.
}
}
}
Maintenant, je me demande si c'est la bonne approche ou dois-je lever l'exception. Je peux éviter les exceptions, car retourner serait la même chose que d'itérer sur une collection vide, ce qui signifie qu'aucun code important n'est exécuté de toute façon, mais d'un autre côté, je cache peut-être des problèmes quelque part dans le code, car pourquoi quelqu'un voudrait-il appeler DeleteItems
avec null
paramètre? Cela peut indiquer qu'il y a un problème ailleurs dans le code.
C'est un problème que j'ai généralement avec les méthodes dans les services, car la plupart d'entre elles font quelque chose et ne renvoient pas de résultat, donc si quelqu'un transmet des informations invalides, il n'y a rien à faire pour le service, donc il revient.
Réponses:
Ce sont deux questions différentes.
Devriez-vous accepter
null
? Cela dépend de votre politique généralenull
dans la base de code. À mon avis, interdirenull
partout sauf là où cela est explicitement documenté est une très bonne pratique, mais c'est encore mieux de s'en tenir à la convention que votre base de code a déjà.Devriez-vous accepter la collection vide? À mon avis: OUI, absolument. Il faut beaucoup plus d'efforts pour restreindre tous les appelants à des collections non vides que pour faire ce qui est mathématiquement juste - même si cela surprend certains développeurs qui ne savent pas exactement le concept de zéro.
la source
AhaINoticedYouPassingInNullException
lorsque le runtime vous offre déjà la possibilité de lancerNullReferenceException
pour vous, sans que vous n'écrivez de code du tout. Il existe un certain utilitaire (par exemple, votre outil de couverture de code vous dira si vous avez ou non un test unitaire pour passer null dans le premier cas mais pas dans le second), mais aucune exception ne devrait être essayée / interceptée à chaque appel au service, car c'est généralement une erreur de programmeur.NullReferenceException
niAhaINoticedYouPassingInNullException
n'importe où, sauf dans un code de récupération après sinistre de haut niveau. Et ce gestionnaire d'exceptions devrait probablement créer un rapport de bogue :-)null
- les contrôleurs contiennent-ils un passe-partout à attraper et à continuer dans ce cas également?ArgumentNullException
Lancer explicitement un est supérieur à permettre au code intérieur de lancer unNullReferenceException
- en regardant simplement le message d'exception, il est évident qu'il s'agit d'une erreur d'entrée plutôt que d'une erreur logique dans le corps de la méthode sur le site de lancement, et garantir une sortie précoce signifie que vous êtes plus susceptible d'avoir laissé d'autres données dans un état valide plutôt que partiellement muté à partir d'un null inattendu ultérieurement.Valeur nulle
Comme l'a déjà dit @KilianFoth, respectez votre politique générale. Si cela doit être considéré
null
comme un "raccourci" pour une liste vide, faites-le de cette façon.Si vous n'avez pas de politique cohérente sur les
null
valeurs, je recommanderais la suivante:null
devrait être réservé pour représenter des situations qui ne peuvent pas être exprimées par le type "normal", par exemple en utilisantnull
pour représenter "je ne sais pas". Et c'est un bon choix, car tous ceux qui essaient d'utiliser cette valeur sans précaution recevront une exception, ce qui est la bonne chose.L'utilisation
null
comme raccourci pour une liste vide ne se qualifie pas de cette façon, car il existe déjà une représentation parfaite, étant une liste avec zéro élément. Et c'est un mauvais choix technique, car il oblige chaque partie de votre code traitant des listes à vérifier la sténographie validenull
.Liste vide
Pour une
DeleteItems()
méthode, passer une liste vide signifie effectivement ne rien faire. J'autoriserais cela comme argument, sans lever d'exception, mais simplement revenir rapidement.Bien sûr, l'appelant pourrait d'abord vérifier l'absence d'éléments et ignorer l'
DeleteItems()
appel dans ce cas. Si nous parlons d'une API Web, pour des raisons d'efficacité, l'appelant devrait en fait le faire pour éviter le trafic inutile et les latences aller-retour. Mais je ne pense pas que votre API devrait appliquer cela.la source
Lancez une exception et gérez les valeurs NULL dans le code appelant.
En règle générale, essayez d'éviter null en tant que valeurs de paramètre. Cela réduira les NullPointerExceptions en général, car les valeurs nulles seront vraiment une exception.
En plus de cela, regardez le reste de votre code. S'il s'agit d'un modèle courant dans votre projet, restez cohérent.
la source
De manière générale, la levée d'exceptions devrait être réservée à des situations exceptionnelles, c'est-à-dire si le code n'a pas de ligne de conduite raisonnable à prendre dans le contexte actuel.
Vous pouvez appliquer ce processus de réflexion à cette situation. Étant donné qu'il s'agit d'une classe publique avec une méthode publique, vous avez une API publique et en théorie aucun contrôle sur ce qui lui est transmis.
Votre code n'a aucun contexte sur ce qui l'appelle (comme il ne devrait pas), et il n'y a rien que vous puissiez raisonnablement faire avec une valeur nulle. Ce serait certainement un candidat pour un
ArgumentNullException
.la source
null
?null
vous, vous n'avez pas de collection. Si le code appelant est supposé / devrait fournir une collection à la méthode, il y a quelque chose qui ne va pas, vous devriez donc lancer. La seule raison de traiter un null de la même manière qu'une collection vide est si vous pouvez raisonnablement vous attendre à ce que le code appelant produise des collections null. Comme d'autres réponses l'ont noté, la plupart du temps, quelque chosenull
est une anomalie. Si vous les traitez de la même manière que les collections vides, vous ignorez potentiellement un problème ailleurs dans le code.null
parlez de vide, cela dépend du contexte de cette méthode. Quelque part ailleurs dans la même base de code, vous pourriez avoir un paramètreIEnumerable
ouIContainer
qui effectue une sorte de filtrage,null
pourrait signifier «pas de filtre» (tout autoriser) tandis qu'un filtre vide signifie ne rien autoriser. Et dans un autre endroit, celanull
pourrait signifier explicitement "je ne sais pas". Donc, étant donné quenull
cela ne signifie pas toujours exactement la même chose partout, c'est une bonne idée de ne pas inventer de sens du tout, à moins que ce sens ne soit nécessaire ou au moins utile à quelqu'un.Cette question ne semble pas concerner les exceptions, mais
null
être un argument valable.Donc, vous devez d'abord et avant tout décider s'il
null
s'agit d'une valeur autorisée pour votre argument de cette méthode. Si c'est le cas, vous n'avez pas besoin d'une exception. Si ce n'est pas le cas, vous avez besoin d'une exception.Que vous souhaitiez autoriser
null
ou non est discutable, comme en témoignent de nombreux hits Google à ce sujet. Cela signifie que vous n'obtiendrez pas de réponse claire et que cela dépend quelque peu de l'opinion et de la tradition de l'endroit où vous travaillez.Un autre point litigieux est de savoir si une fonction de bibliothèque doit être vraiment stricte à ce sujet, ou aussi indulgente que possible, tant qu'elle n'essaie pas de «corriger» des paramètres erronés. Comparez cela au monde des protocoles réseau, du transfert de courrier, etc. (qui sont des contrats d'interface, tout comme les méthodes de programmation). Là, généralement, la politique est que l'expéditeur doit se conformer le plus strictement possible au protocole, tandis que le récepteur doit se mettre en quatre pour pouvoir travailler avec tout ce qui se présente.
Vous devez donc décider: est-ce vraiment le travail d'une méthode de bibliothèque d'appliquer une politique assez large comme la
null
gestion? Surtout si votre bibliothèque est également utilisée par d'autres personnes (qui peuvent avoir des politiques différentes).Je préférerais probablement autoriser les
null
valeurs, définir et documenter leur sémantique (c'est-null = empty array
à- dire dans ce cas), et ne pas lever d'exception, à moins que 99% de votre autre code similaire (code de style "bibliothèque") ne le fasse dans l'autre sens. 'rond.la source
null
sur le principe d'être libéral dans ce que vous acceptez, alors la journalisation ou même le lancement serait utile aux personnes dont l' intention est d'être stricte dans ce qu'elles transmettent, mais qui ont bousillé leur code et leurs tests unitaires dans la mesure où ils réussissent denull
toute façon.null
, mais de déclarer ouvertement dans le contrat de la méthode qu'elle est acceptable (ou non, selon la solution proposée par le PO), puis la question de savoir si lever une exception (ou pas) se résout.