Donc je rencontre souvent cette situation ... où Do.Something(...)
renvoie une collection nulle, comme ceci:
int[] returnArray = Do.Something(...);
Ensuite, j'essaie d'utiliser cette collection comme ceci:
foreach (int i in returnArray)
{
// do some more stuff
}
Je suis juste curieux, pourquoi une boucle foreach ne peut-elle pas fonctionner sur une collection nulle? Il me semble logique que 0 itérations soient exécutées avec une collection nulle ... au lieu de cela, elle lance unNullReferenceException
. Quelqu'un sait pourquoi cela pourrait être?
C'est ennuyeux car je travaille avec des API qui ne savent pas exactement ce qu'elles renvoient, donc je me retrouve avec if (someCollection != null)
partout ...
Edit: Merci à tous d'avoir expliqué que les foreach
utilisations GetEnumerator
et s'il n'y a pas d'énumérateur à obtenir, le foreach échouerait. Je suppose que je demande pourquoi le langage / runtime ne peut pas ou ne fera pas de vérification nulle avant de saisir l'énumérateur. Il me semble que le comportement serait encore bien défini.
null
valeur. Suggérez-vous cela uniquement pour lesforeach
boucles ou autres instructions?Réponses:
Eh bien, la réponse courte est "parce que c'est la façon dont les concepteurs de compilateurs l'ont conçue". En réalité, cependant, votre objet de collection est nul, il n'y a donc aucun moyen pour le compilateur d'obtenir l'énumérateur pour parcourir la collection.
Si vous avez vraiment besoin de faire quelque chose comme ça, essayez l'opérateur de coalescence nulle:
la source
GetEnumerator
le résultatUne
foreach
boucle appelle laGetEnumerator
méthode.Si la collection l'est
null
, cet appel de méthode aboutit à aNullReferenceException
.Il est inapproprié de renvoyer une
null
collection; vos méthodes devraient renvoyer une collection vide à la place.la source
int[] returnArray = Do.Something() ?? new int[] {};
... ?? new int[0]
.Il existe une grande différence entre une collection vide et une référence nulle à une collection.
Lorsque vous utilisez
foreach
, en interne, cela appelle la méthode GetEnumerator () de IEnumerable . Lorsque la référence est nulle, cela déclenche cette exception.Cependant, il est parfaitement valable d'avoir un
IEnumerable
ou videIEnumerable<T>
. Dans ce cas, foreach "n'itérera" rien (puisque la collection est vide), mais il ne lancera pas non plus, car c'est un scénario parfaitement valide.Éditer:
Personnellement, si vous devez contourner ce problème, je recommanderais une méthode d'extension:
Vous pouvez alors simplement appeler:
la source
Il s'agit d'une réponse depuis longtemps, mais j'ai essayé de le faire de la manière suivante pour éviter simplement l'exception de pointeur nul et peut être utile pour quelqu'un qui utilise l'opérateur de vérification null C #?.
la source
null
) la généralisation de l'ensemble de la boucle à l'écran LCD deEnumerable
(comme on le??
ferait), b) la nécessité d'ajouter une méthode d'extension à chaque projet, et c) il faut éviternull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) pour commencer.Une autre méthode d'extension pour contourner ce problème:
Consommer de plusieurs façons:
(1) avec une méthode qui accepte
T
:(2) avec une expression:
(3) avec une méthode anonyme multiligne
la source
Console.WriteLine
n'est qu'un exemple d'une méthode qui prend un argument (anAction<T>
). Les éléments 1, 2 et 3 montrent des exemples de passage de fonctions à la.ForEach
méthode d'extension.null
) généralisant toute la boucle à l'écran LCD deEnumerable
(comme l' utilisation??
serait ), b) nécessitent d'ajouter une méthode d'extension à chaque projet, ou c) nécessitent d'éviternull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) pour commencer (cuz,null
signifie N / A, tandis que la liste vide signifie, c'est appl. mais est actuellement, eh bien, vide !, c'est-à-dire qu'un employeur pourrait avoir des commissions N / A pour les non-ventes ou vide pour les ventes).Écrivez simplement une méthode d'extension pour vous aider:
la source
Parce qu'une collection null n'est pas la même chose qu'une collection vide. Une collection vide est un objet de collection sans éléments; une collection null est un objet inexistant.
Voici quelque chose à essayer: Déclarez deux collections de toute sorte. Initialisez l'un normalement pour qu'il soit vide et affectez à l'autre la valeur
null
. Essayez ensuite d'ajouter un objet aux deux collections et voyez ce qui se passe.la source
C'est la faute de
Do.Something()
. La meilleure pratique ici serait de renvoyer un tableau de taille 0 (c'est possible) au lieu d'un null.la source
Parce que dans les coulisses l'
foreach
acquiert un énumérateur, équivalent à ceci:la source
null
références, par exemple lors de l'accès aux membres. Il s'agit généralement d'une erreur, et si ce n'est pas le cas, il est assez simple de gérer cela, par exemple avec la méthode d'extension qu'un autre utilisateur a fournie comme réponse.Je pense que l'explication de la raison pour laquelle l'exception est levée est très claire avec les réponses fournies ici. Je souhaite simplement compléter la façon dont je travaille habituellement avec ces collections. Parce que, parfois, j'utilise la collection plus d'une fois et je dois tester si elle est nulle à chaque fois. Pour éviter cela, je fais ce qui suit:
De cette façon, nous pouvons utiliser la collection autant que nous le voulons sans craindre l'exception et nous ne polluons pas le code avec des instructions conditionnelles excessives.
L'utilisation de l'opérateur de vérification nulle
?.
est également une excellente approche. Mais, dans le cas de tableaux (comme l'exemple dans la question), il doit être transformé en List avant:la source
ForEach
méthode est l'une des choses que je déteste dans une base de code.la source