Existe-t-il un moyen plus agréable de procéder comme suit:
J'ai besoin d'une vérification pour que null apparaisse sur file.Headers avant de poursuivre la boucle
if (file.Headers != null)
{
foreach (var h in file.Headers)
{
//set lots of properties & some other stuff
}
}
En bref, il semble un peu moche d’écrire le foreach à l’intérieur du if en raison du niveau d’indentation dans mon code.
Est-ce quelque chose qui évaluerait à
foreach(var h in (file.Headers != null))
{
//do stuff
}
possible?
Juste comme un ajout cosmétique à la suggestion de Rune, vous pouvez créer votre propre méthode d’extension:
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
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 soit T, vous pouvez le faire.
foreach(var header in file.Headers ?? Enumerable.Empty<T>()){
//do stuff
}
cela créera un énumérable vide de T si file.Headers est null. Si le type de fichier est un type que vous possédez, je souhaiterais toutefois modifier le getter de Headers
à la place. 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", alors que null doit (en fait) être interprété comme "je ne sais pas s'il y a des éléments", utilisez un ensemble vide pour montrer 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 le contrôle nul aussi souvent.
EDITpour donner suite à la suggestion de Jons, vous pouvez également créer une méthode d’extension transformant le code ci-dessus en
foreach(var header in file.Headers.OrEmptyIfNull()){
//do stuff
}
Dans le cas où vous ne pouvez pas changer le getter, ce serait ma préférence, car il exprime plus clairement l'intention en donnant à l'opération un nom (OrEmptyIfNull).
Franchement, je conseille: il suffit de sucer le test null
. Un test null
est just une brfalse
ou brfalse.s
; tout le reste impliquera beaucoup plus de travail (tests, assignations, appels de méthodes supplémentaires, GetEnumerator()
, MoveNext()
, Dispose()
inutiles, sur l'itérateur, etc.).
Un test if
est 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 vous perturbe, vous pouvez modifier le si pour vérifier:
if(file.Headers == null)
return;
et vous ne pourrez accéder à la boucle foreach que lorsqu'il existe une valeur vraie à la propriété d'en-têtes.
une autre option à laquelle je peux penser est d'utiliser l'opérateur null-coalescing à l'intérieur de votre boucle foreach et d'éviter complètement la vérification de null ..
List<int> collection = new List<int>();
collection = null;
foreach (var i in collection ?? Enumerable.Empty<int>())
{
//your code here
}
(remplacez la collection par votre vrai objet/type)
J'utilise une petite méthode d'extension Nice pour ces scénarios:
public static class Extensions
{
public static IList<T> EnsureNotNull<T>(this IList<T> list)
{
return list ?? new List<T>();
}
}
Étant donné que Headers est de type list, vous pouvez faire ce qui suit:
foreach(var h in (file.Headers.EnsureNotNull()))
{
//do stuff
}
Utilisation de Opérateur Null-conditionnel et ForEach () qui fonctionne plus rapidement que la boucle standard foreach.
Vous devez cependant 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 partant du principe que 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, donc la contrainte de type IEnumerable<T>
est peut-être redondante.
public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection)
where TCollection: class, IEnumerable<T>, new()
{
return collection ?? new TCollection();
}