Je rencontre souvent du code comme celui-ci:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
Fondamentalement, la if
condition garantit que le foreach
bloc ne s'exécutera que s'il items
n'est pas nul. Je me demande si la if
condition est vraiment nécessaire, ouforeach
va gérer le cas si items == null
.
Je veux dire, puis-je simplement écrire
foreach(T item in items)
{
//...
}
sans se soucier de savoir si items
est nul ou non? La if
condition est-elle superflue? Ou cela dépend du type de items
ou peut-être T
aussi?
null
) la généralisation de la boucle entière à l'écran LCDEnumerable
(comme le??
ferait ), b) nécessitent l'ajout d'une méthode d'extension à chaque projet, ou c) nécessitent d'éviternull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) pour commencer par (cuz,null
signifie N / A, alors qu'une liste vide signifie, c'est appl. mais est actuellement, eh bien, vide !, c'est-à-dire qu'un employeur pourrait avoir des commissions qui sont N / A pour les non-ventes ou vides pour les ventes quand ils n'en ont pas gagné).Réponses:
Vous devez toujours vérifier si (items! = Null) sinon vous obtiendrez NullReferenceException. Cependant, vous pouvez faire quelque chose comme ceci:
mais vous pouvez en vérifier les performances. Donc je préfère toujours avoir if (items! = Null) en premier.
Sur la base de la suggestion d'Eric Lippert, j'ai changé le code en:
la source
IEnumerable<T>
qui à son tour se dégrade en énumérateur en une interface rendant l'itération plus lente. Mon test a montré une dégradation du facteur 5 pour l'itération sur un tableau int.En utilisant C # 6, vous pouvez utiliser le nouvel opérateur conditionnel null avec
List<T>.ForEach(Action<T>)
(ou votre propreIEnumerable<T>.ForEach
méthode d'extension).la source
null
) la généralisation de la boucle entière à l'écran LCD deEnumerable
(comme le??
ferait l' utilisation ), b) nécessite l'ajout d'une méthode d'extension à chaque projet, ou c ) nécessitent d'éviternull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) pour commencer par (cuz,null
signifie N / A, alors qu'une liste vide signifie, c'est appl. mais est actuellement, eh bien, vide !, c'est-à-dire qu'un Empl. N / A pour les non-ventes ou vide pour les ventes quand ils n'en ont pas gagné).items
c'est unList<T>
bien, plutôt que n'importe lequelIEnumerable<T>
. (Ou ayez une méthode d'extension personnalisée, que vous avez dit que vous ne voulez pas qu'il y ait ...) De plus, je dirais que cela ne vaut vraiment pas la peine d'ajouter 11 commentaires, tous disant essentiellement que vous aimez une réponse particulière.foreach
. En particulier pour une liste qui, je pense, est convertie enfor
boucle.La vraie chose à retenir ici devrait être qu'une séquence ne devrait presque jamais être nulle en premier lieu . Faites simplement en un invariant dans tous vos programmes que si vous avez une séquence, elle n'est jamais nulle. Il est toujours initialisé pour être la séquence vide ou une autre séquence authentique.
Si une séquence n'est jamais nulle, vous n'avez évidemment pas besoin de la vérifier.
la source
null
) la généralisation de la boucle entière à l'écran LCDEnumerable
(comme le??
ferait ), b) nécessitent l'ajout d'une méthode d'extension à chaque projet, ou c) nécessitent d'éviternull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) pour commencer par (cuz,null
signifie N / A, alors qu'une 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 vides pour les ventes quand ils n'en ont pas gagné).En fait, il y a une demande de fonctionnalité sur ce @Connect: http://connect.microsoft.com/VisualStudio/feedback/details/93497/foreach-should-check-for-null
Et la réponse est assez logique:
la source
Vous pouvez toujours le tester avec une liste nulle ... mais c'est ce que j'ai trouvé sur le site Web de msdn
la source
Ce n'est pas superfleux. Au moment de l'exécution, les éléments seront convertis en un IEnumerable et sa méthode GetEnumerator sera appelée. Cela entraînera un déréférencement des éléments qui échoueront
la source
IEnumerable
et 2) C'est une décision de conception de la faire lancer. C # pourrait facilement insérer cettenull
vérification si les développeurs considéraient que c'était une bonne idée.Vous pouvez encapsuler la vérification null dans une méthode d'extension et utiliser un lambda:
Le code devient:
Cela peut être encore plus concis si vous souhaitez simplement appeler une méthode qui prend un élément et renvoie
void
:la source
Vous en avez besoin. Vous obtiendrez une exception lorsque vous
foreach
accéderez au conteneur pour configurer l'itération dans le cas contraire.Sous les couvertures,
foreach
utilise une interface implémentée sur la classe de collection pour effectuer l'itération. L'interface équivalente générique est ici .la source
Le test est nécessaire, car si la collection est nulle, foreach lèvera une NullReferenceException. C'est en fait assez simple de l'essayer.
la source
le second lancera un
NullReferenceException
avec le messageObject reference not set to an instance of an object.
la source
Comme mentionné ici, vous devez vérifier s'il n'est pas nul.
la source
En C # 6, vous pouvez écrire qc comme ceci:
C'est essentiellement la solution de Vlad Bezden mais en utilisant le ?? expression pour toujours générer un tableau qui n'est pas nul et qui survit donc au foreach plutôt que d'avoir cette vérification à l'intérieur du crochet foreach.
la source