Rechercher null dans la boucle foreach

Y a-t-il une meilleure façon de faire ce qui suit:
J’ai besoin d’un chèque pour que null se produise sur le fichier.Headers avant de procéder à la boucle

if (file.Headers != null) { foreach (var h in file.Headers) { //set lots of properties & some other stuff } } 

En bref, cela semble un peu moche d’écrire le foreach dans le if en raison du niveau d’indentation qui se produit dans mon code.

Est-ce quelque chose qui évaluerait

 foreach(var h in (file.Headers != null)) { //do stuff } 

possible?

Juste comme un léger ajout cosmétique à la suggestion de Rune, vous pouvez créer votre propre méthode d’extension:

 public static IEnumerable OrEmptyIfNull(this IEnumerable source) { return source ?? Enumerable.Empty(); } 

Ensuite, vous pouvez écrire:

 foreach (var header in file.Headers.OrEmptyIfNull()) { } 

Changer le nom selon les goûts 🙂

En supposant que le type d’éléments dans file.Headers est T vous pouvez le faire

 foreach(var header in file.Headers ?? Enumerable.Empty()){ //do stuff } 

Cela créera un énumérateur vide de T si fichier.Headers est nul. Si le type de fichier est un type que vous possédez, je considérerais toutefois de changer le getter des en- Headers . null est la valeur de unknown donc si possible, au lieu d’utiliser null comme “je sais qu’il n’y a pas d’éléments” quand null en fait (/ initialement) doit être interprété comme “je ne sais pas s’il y a des éléments” vous savez qu’il n’y a pas d’éléments dans l’ensemble. Ce serait aussi DRY’er puisque vous n’aurez pas à faire la vérification null aussi souvent.

EDIT en tant que suivi de la suggestion de Jons, vous pouvez également créer une méthode d’extension pour modifier le code ci-dessus.

 foreach(var header in file.Headers.OrEmptyIfNull()){ //do stuff } 

Dans le cas où vous ne pouvez pas changer le getter, ce serait le mien, car il exprime plus clairement l’intention en donnant un nom à l’opération (OrEmptyIfNull).

Franchement, je vous conseille: aspirez simplement le test null . Un test null est juste un brfalse ou un brfalse.s ; tout le rest va impliquer beaucoup plus de travail (tests, affectations, appels de méthodes supplémentaires, GetEnumerator() , MoveNext() , Dispose() inutiles sur l’iterator, etc.).

Un test if simple, évident et efficace.

le “si” avant l’itération est correct, peu de ces “jolies” sémantiques peuvent rendre votre code moins lisible.

de toute façon, si l’indentation perturbe votre, vous pouvez changer le si pour vérifier:

 if(file.Headers == null) return; 

et vous obtiendrez la boucle foreach uniquement lorsqu’il existe une valeur vraie dans la propriété headers.

une autre option à laquelle je peux penser consiste à utiliser l’opérateur null-coalescing dans votre boucle foreach et à éviter complètement la vérification de null. échantillon:

 List collection = new List(); collection = null; foreach (var i in collection ?? Enumerable.Empty()) { //your code here } 

(remplacez la collection par votre véritable object / type)

J’utilise une petite méthode d’extension intéressante pour ces scénarios:

  public static class Extensions { public static IList EnsureNotNull(this IList list) { return list ?? new List(); } } 

Étant donné que les en-têtes sont de type liste, vous pouvez effectuer les opérations suivantes:

 foreach(var h in (file.Headers.EnsureNotNull())) { //do stuff } 

Utilisation de l’ opérateur Null-conditionnel et de ForEach () qui fonctionnent plus rapidement que la boucle foreach standard.
Vous devez toutefois convertir la collection en liste.

  listOfItems?.ForEach(item => // ... ); 

Dans certains cas, je préférerais légèrement une autre variante générique, en supposant que, en règle générale, les constructeurs de collection par défaut renvoient des instances vides.

Il serait préférable de nommer cette méthode NewIfDefault . Cela peut être utile non seulement pour les collections, alors la contrainte de type IEnumerable est peut-être redondante.

 public static TCollection EmptyIfDefault(this TCollection collection) where TCollection: class, IEnumerable, new() { return collection ?? new TCollection(); }