A menudo me encuentro con un código como el siguiente:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
Básicamente, la if
condición asegura que el foreach
bloque se ejecutará solo si items
no es nulo. Me pregunto si la if
condición es realmente necesaria, o foreach
manejaré el caso si items == null
.
Quiero decir, puedo simplemente escribir
foreach(T item in items)
{
//...
}
sin preocuparse de si items
es nulo o no? ¿La if
condición es superflua? ¿O esto depende del tipo de items
o quizás T
también?
null
) generalizar todo el ciclo a la pantalla LCD deEnumerable
(como lo??
haría el uso ), b) requieren agregar un método de extensión a cada proyecto, o c) requieren evitarnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) para comenzar con (cuz,null
significa N / A, mientras que la lista vacía significa, es aplicable pero es actualmente, bueno, ¡ vacío !, es decir, un Empl. podría tener comisiones que son N / A para no ventas o vacío para ventas cuando no han ganado ninguna).Respuestas:
Aún debe verificar si (items! = Null); de lo contrario, obtendrá NullReferenceException. Sin embargo, puede hacer algo como esto:
pero puede comprobar su rendimiento. Así que todavía prefiero tener if (items! = Null) primero.
Según la sugerencia de Lippert de Eric, cambié el código a:
fuente
IEnumerable<T>
que a su vez se degrada a enumerador a una interfaz que hace que la iteración sea más lenta. Mi prueba mostró una degradación de factor 5 para la iteración sobre una matriz int.Usando C # 6, podría usar el nuevo operador condicional nulo junto con
List<T>.ForEach(Action<T>)
(o su propioIEnumerable<T>.ForEach
método de extensión).fuente
null
) generalizar todo el ciclo a la pantalla LCD deEnumerable
(como lo??
haría el uso ), b) requiere agregar un método de extensión a cada proyecto, o c ) requieren evitarnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) para comenzar con (cuz,null
significa N / A, mientras que la lista vacía significa que es aplicable pero actualmente, bueno, ¡está vacío !, es decir, un Empl. podría tener Comisiones que son N / A para no ventas o vacío para ventas cuando no han ganado).items
es un pensamientoList<T>
, en lugar de cualquieraIEnumerable<T>
. (O tenga un método de extensión personalizado, que ha dicho que no quiere que haya ...) Además, yo diría que realmente no vale la pena agregar 11 comentarios, todos básicamente diciendo que le gusta una respuesta en particular.foreach
. Particularmente para una lista que creo que se convierte en unfor
bucle.La conclusión real aquí debería ser una secuencia que casi nunca debería ser nula en primer lugar . Simplemente conviértalo en un invariante en todos sus programas que si tiene una secuencia, nunca es nulo. Siempre se inicializa para que sea la secuencia vacía o alguna otra secuencia genuina.
Si una secuencia nunca es nula, obviamente no es necesario verificarla.
fuente
null
) generalizar todo el ciclo a la pantalla LCD deEnumerable
(como lo??
haría el uso ), b) requieren agregar un método de extensión a cada proyecto, o c) requieren evitarnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) para comenzar con (cuz,null
significa N / A, mientras que la lista vacía significa, es aplicable pero es actualmente, bueno, ¡ vacío !, es decir, un Empl. podría tener comisiones que son N / A para no ventas o vacío para ventas cuando no han ganado ninguna).En realidad, hay una solicitud de función en ese @Connect: http://connect.microsoft.com/VisualStudio/feedback/details/93497/foreach-should-check-for-null
Y la respuesta es bastante lógica:
fuente
Siempre puede probarlo con una lista nula ... pero esto es lo que encontré en el sitio web de msdn
fuente
No es superfluo. En tiempo de ejecución, los elementos se convertirán en un IEnumerable y se llamará a su método GetEnumerator. Eso provocará una desreferenciación de elementos que fallarán
fuente
IEnumerable
y 2) Es una decisión de diseño hacerla lanzar. C # podría insertar fácilmente esenull
cheque si los desarrolladores lo consideraran una buena idea.Puede encapsular la verificación nula en un método de extensión y usar una lambda:
El código se convierte en:
Si puede ser aún más conciso si solo desea llamar a un método que toma un elemento y devuelve
void
:fuente
Necesitas esto. Obtendrá una excepción cuando
foreach
acceda al contenedor para configurar la iteración de lo contrario.Debajo de las cubiertas,
foreach
utiliza una interfaz implementada en la clase de colección para realizar la iteración. La interfaz equivalente genérica está aquí .fuente
La prueba es necesaria, porque si la colección es nula, foreach lanzará una NullReferenceException. De hecho, es bastante sencillo probarlo.
fuente
el segundo lanzará un
NullReferenceException
con el mensajeObject reference not set to an instance of an object.
fuente
Como se mencionó aquí , debe verificar si no es nulo.
fuente
En C # 6 puedes escribir algo como esto:
Es básicamente la solución de Vlad Bezden, pero usando el ?? expresión para generar siempre una matriz que no sea nula y, por lo tanto, sobreviva al foreach en lugar de tener esta comprobación dentro del corchete foreach.
fuente