¿Existe una forma mejor de hacer lo siguiente
? Necesito una verificación para que no se produzca un valor nulo en el archivo. Encabezados antes de continuar con el bucle
if (file.Headers != null)
{
foreach (var h in file.Headers)
{
//set lots of properties & some other stuff
}
}
En resumen, parece un poco feo escribir el foreach dentro del if debido al nivel de sangría que ocurre en mi código.
Es algo que evaluaría
foreach(var h in (file.Headers != null))
{
//do stuff
}
¿posible?
Respuestas:
Solo como una pequeña adición cosmética a la sugerencia de Rune, puede crear su propio método de extensión:
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source) { return source ?? Enumerable.Empty<T>(); }
Entonces puedes escribir:
foreach (var header in file.Headers.OrEmptyIfNull()) { }
Cambie el nombre según el gusto :)
fuente
Suponiendo que el tipo de elementos en file.Headers es T, podría hacer esto
foreach(var header in file.Headers ?? Enumerable.Empty<T>()){ //do stuff }
esto creará un enumerable vacío de T si file.Headers es nulo. Sin embargo, si el tipo de archivo es de su propiedad, consideraría cambiar el captador de
Headers
.null
es el valor de desconocido, así que si es posible, en lugar de usar nulo como "Sé que no hay elementos" cuando nulo en realidad (/ originalmente) debe interpretarse como "No sé si hay elementos", use un conjunto vacío para mostrar que sabes que no hay elementos en el conjunto. Eso también sería DRY'er ya que no tendrá que hacer la verificación nula con tanta frecuencia.EDITAR como seguimiento de la sugerencia de Jon, también puede crear un método de extensión cambiando el código anterior a
foreach(var header in file.Headers.OrEmptyIfNull()){ //do stuff }
En el caso de que no pueda cambiar el getter, este sería mi preferido, ya que expresa la intención más claramente al darle un nombre a la operación (OrEmptyIfNull)
El método de extensión mencionado anteriormente puede hacer que ciertas optimizaciones sean imposibles de detectar para el optimizador. Específicamente, aquellos que están relacionados con IList usando métodos de sobrecarga, esto se puede eliminar.
public static IList<T> OrEmptyIfNull<T>(this IList<T> source) { return source ?? Array.Empty<T>(); }
fuente
null
) degenerar todo el bucle a LCD deIEnumerable<T>
(como usar ?? would), b) requiere agregar un método de extensión a cada proyecto, o c) requiere evitarnull
IEnumerables
(Pffft! Puh-LEAZE! SMH.) para comenzar (cuznull
significa N / A, mientras que la lista vacía significa, es aplicable pero actualmente, bueno, ¡vacío !, es decir, un Empleado podría tener Comisiones N / A para no Ventas o vacío para Ventas cuando no ha ganado ninguna).IEnumerable
sean más restrictivos que losforeach
requisitos, pero menos restrictivos que los requisitos deList<T>
la respuesta a la que se vincula. Que tienen la misma penalización de rendimiento que probar si el enumerable es nulo.List<T>
.Francamente, le aconsejo: simplemente aguante la
null
prueba. UNAnull
prueba es solo unabrfalse
obrfalse.s
; todo lo demás va a implicar mucho más trabajo (pruebas, tareas, llamadas de método adicional innecesarioGetEnumerator()
,MoveNext()
,Dispose()
en el iterador, etc).Un
if
prueba es simple, obvia y eficiente.fuente
el "si" antes de la iteración está bien, pocas de esas semánticas "bonitas" pueden hacer que su código sea menos legible.
de todos modos, si la sangría le molesta, puede cambiar si desea comprobar:
if(file.Headers == null) return;
y llegará al bucle foreach solo cuando haya un valor verdadero en la propiedad de encabezados.
otra opción en la que puedo pensar es usar el operador de fusión nula dentro de su bucle foreach y evitar por completo la verificación de nulos. muestra:
List<int> collection = new List<int>(); collection = null; foreach (var i in collection ?? Enumerable.Empty<int>()) { //your code here }
(reemplace la colección con su verdadero objeto / tipo)
fuente
Usando el operador condicional nulo y ForEach () que funciona más rápido que el bucle foreach estándar.
Sin embargo, tienes que lanzar la colección a List.
listOfItems?.ForEach(item => // ... );
fuente
Estoy usando un pequeño método de extensión para estos escenarios:
public static class Extensions { public static IList<T> EnsureNotNull<T>(this IList<T> list) { return list ?? new List<T>(); } }
Dado que los encabezados son de tipo lista, puede hacer lo siguiente:
foreach(var h in (file.Headers.EnsureNotNull())) { //do stuff }
fuente
??
operador y acortar la declaración de retorno areturn list ?? new List<T>;
null
su muestrafile.Headers.EnsureNotNull() != null
no es necesaria, ¿e incluso es incorrecta?Para algunos casos, preferiría una variante genérica ligeramente diferente, asumiendo que, como regla, los constructores de colección predeterminados devuelven instancias vacías.
Sería mejor nombrar este método
NewIfDefault
. Puede ser útil no solo para colecciones, por lo que la restricción de tipoIEnumerable<T>
puede ser redundante.public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection) where TCollection: class, IEnumerable<T>, new() { return collection ?? new TCollection(); }
fuente