c# singleton ienumerable empty-list

¿Hay un singleton de "Lista vacía" en C#?



ienumerable empty-list (7)

Creo que agregar un método de extensión es una alternativa limpia gracias a su capacidad para manejar nulos, algo como:

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> list) { return list ?? Enumerable.Empty<T>(); } foreach(var x in xs.EmptyIfNull()) { ... }

En C # uso LINQ y IEnumerable un poco. Y todo está bien y es bueno (o al menos en su mayoría).

Sin embargo, en muchos casos me encuentro con que necesito un IEnumerable<X> vacío como predeterminado. Es decir, me gustaría

for (var x in xs) { ... }

Para trabajar sin necesidad de una comprobación nula. Ahora, esto es lo que hago actualmente, dependiendo del contexto más amplio:

var xs = f() ?? new X[0]; // when xs is assigned, sometimes for (var x in xs ?? new X[0]) { ... } // inline, sometimes

Ahora, mientras que lo anterior está perfectamente bien para mí , es decir, si hay una "sobrecarga adicional" con la creación del objeto de matriz, simplemente no me importa , me preguntaba:

¿Hay un singleton "IEnumerable / IList" inmutable vacío en C # / .NET? (Y, incluso si no, ¿hay una forma "mejor" de manejar el caso descrito anteriormente?)

Java tiene Collections.EMPTY_LIST singleton inmutable - "bien escrito" a través de Collections.emptyList<T>() - que sirve a este propósito, aunque no estoy seguro si un concepto similar podría funcionar en C # porque los genéricos se manejan de manera diferente.

Gracias.


Creo que estás buscando Enumerable.Empty<T>() .

Singleton lista vacía no tiene mucho sentido, porque las listas a menudo son mutables.


En su ejemplo original, usa una matriz vacía para proporcionar un enumerable vacío. Si bien usar Enumerable.Empty<T>() es perfectamente correcto, puede haber otros casos: si tiene que usar una matriz (o la interfaz IList<T> ), puede usar el método

System.Array.Empty<T>()

Lo que ayuda a evitar asignaciones innecesarias.

Notas / Referencias:


Está buscando Enumerable.Empty<int>();

En otras noticias, la lista vacía de Java apesta porque la interfaz de la Lista expone los métodos para agregar elementos a la lista que generan excepciones.


Microsoft implementó ''Any ()'' como este ( source )

public static bool Any<TSource>(this IEnumerable<TSource> source) { if (source == null) throw new ArgumentNullException("source"); using (IEnumerator<TSource> e = source.GetEnumerator()) { if (e.MoveNext()) return true; } return false; }

Si desea guardar una llamada en la pila de llamadas, en lugar de escribir un método de extensión que llame !Any() , vuelva a escribir y realice estos tres cambios:

public static bool IsEmpty<TSource>(this IEnumerable<TSource> source) //first change (name) { if (source == null) throw new ArgumentNullException("source"); using (IEnumerator<TSource> e = source.GetEnumerator()) { if (e.MoveNext()) return false; //second change } return true; //third change }


Usar Enumerable.Empty<T>() con listas tiene un inconveniente. Si entrega Enumerable.Empty<T> en el constructor de listas, se asigna una matriz de tamaño 4. Pero si entrega una Collection vacía en el constructor de listas, no se produce ninguna asignación. Entonces, si utiliza esta solución en todo su código, lo más probable es que uno de los IEnumerable se utilice para construir una lista, lo que dará como resultado asignaciones innecesarias.