Je rencontre souvent un code comme celui-ci:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
Fondamentalement, la condition if
garantit que le bloc foreach
ne sera exécuté que si items
n'est pas null. Je me demande si la condition if
est vraiment nécessaire ou si foreach
gérera le cas si items == null
.
Je veux dire, je peux simplement écrire
foreach(T item in items)
{
//...
}
sans se soucier de savoir si items
est null ou non? La condition if
est-elle superflue? Ou cela dépend du type de items
ou peut-être de T
également?
Vous devez toujours vérifier si (items! = Null) sinon vous obtiendrez NullReferenceException. Cependant, vous pouvez faire quelque chose comme ça:
List<string> items = null;
foreach (var item in items ?? new List<string>())
{
item.Dump();
}
mais vous pouvez en vérifier les performances. Je préfère donc toujours avoir si (items! = Null) en premier.
Sur la suggestion d'Eric Lippert, j'ai changé le code en:
List<string> items = null;
foreach (var item in items ?? Enumerable.Empty<string>())
{
item.Dump();
}
En utilisant C # 6, vous pouvez utiliser le nouvel opérateur conditionnel null avec List<T>.ForEach(Action<T>)
(ou votre propre méthode IEnumerable<T>.ForEach
extension).
List<string> items = null;
items?.ForEach(item =>
{
// ...
});
La vraie chose à retenir ici devrait être une séquence ne devrait presque jamais être nulle en premier lieu . Faites-en simplement 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, alors vous n'avez évidemment pas besoin de la vérifier.
En réalité, il existe une demande de fonctionnalité sur ce @Connect: http://connect.Microsoft.com/VisualStudio/feedback/details/93497/foreach-should-chould-for-null
Et la réponse est assez logique:
Je pense que la plupart des boucles foreach sont écrit dans l’intention d’itérer un collection non nulle. Si tu essayes itérant via null, vous devriez obtenir votre exception, de sorte que vous pouvez réparer votre code.
Vous pouvez toujours le tester avec une liste nulle ... mais c'est ce que j'ai trouvé sur le site Web msdn
foreach-statement:
foreach ( type identifier in expression ) embedded-statement
Si expression a la valeur null, une exception System.NullReferenceException est levée.
Vous pouvez encapsuler le contrôle nul dans une méthode d'extension et utiliser un lambda:
public static class EnumerableExtensions {
public static void ForEach<T>(this IEnumerable<T> self, Action<T> action) {
if (self != null) {
foreach (var element in self) {
action(element);
}
}
}
}
Le code devient:
items.ForEach(item => {
...
});
If peut être encore plus concis si vous souhaitez simplement appeler une méthode qui prend un élément et renvoie void
:
items.ForEach(MethodThatTakesAnItem);
Ce n'est pas superflous. 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
Vous avez besoin de ça. Vous obtiendrez une exception lorsque foreach
accédera au conteneur pour configurer l'itération autrement.
Sous les couvertures, foreach
utilise une interface implémentée dans la classe de collection pour effectuer l'itération. L’interface générique équivalente est ici .
La déclaration foreach du C # langage (pour chacun dans Visual Basic) cache la complexité de la les recenseurs. Par conséquent, en utilisant foreach est recommandé au lieu de directement manipuler l'énumérateur.
En C # 6, vous pouvez écrire ça comme ceci:
// some string from file or UI, i.e.:
// a) string s = "Hello, World!";
// b) string s = "";
// ...
var items = s?.Split(new char[] { ',', '!', ' ' }) ?? Enumerable.Empty<string>();
foreach (var item in items)
{
//..
}
C'est fondamentalement 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.
Le test est nécessaire, car si la collection est null, foreach lève une exception NullReferenceException. C'est en fait assez simple d'essayer.
List<string> items = null;
foreach(var item in items)
{
Console.WriteLine(item);
}
le second lancera une NullReferenceException
avec le message Object reference not set to an instance of an object.
Comme mentionné ici vous devez vérifier si cela n’est pas nul.
N'utilisez pas une expression dont la valeur est null.