¿Qué es un fragmento de código sólido, elegante y reutilizable para determinar si un IEnumerable está vacío en .NET?

StackOverflow https://stackoverflow.com/questions/117355

  •  02-07-2019
  •  | 
  •  

Pregunta

Estoy tratando de encontrar el fragmento de código más reutilizable pero elegante posible para determinar si se trata de un IEnumerable.Idealmente, esta debería ser una función a la que pueda llamar en cualquier momento que necesite saber si un IEnumerable está vacío.

Si bien he desarrollado una respuesta para .NET 3.5 que me ha funcionado bien hasta ahora, mi pensamiento actual es que no existe una respuesta perfecta, ya que un IEnumerable técnicamente puede encapsular una colección (o cola de iteradores) que modifica los resultados subyacentes como itera, lo que causaría problemas.Sin embargo, esto también sería un impedimento para implementar IEnumerable.Count(), y eso no impidió que MS lo proporcionara.

Así que pensé en ponerlo en SO para ver si alguien tiene uno mejor y en caso de que alguien más lo encuentre útil.

Editar: Vaya, no puedo creer que no supiera sobre IEnumerable.Any.Sabía que existía, pero nunca me molesté en comprobar qué hacía.Que esto sea una lección.Lea la documentación.Sólo porque el nombre de un método no implica que haga lo que usted quiere, no significa que no haga lo que usted quiere.

¿Fue útil?

Solución

!enumerable.Any()

Intentará capturar solo el primer elemento.

Para ampliar cómo y por qué funciona esto, cualquiera determina si alguno de los componentes de un IEnumerable coincide con una función determinada, si no se proporciona ninguna, entonces cualquier componente tendrá éxito, lo que significa que la función devolverá verdadero si existe un elemento en el enumerable.

Otros consejos

Para .net 1/2:

IEnumerator e;
try
{
   e = enumerable.GetEnumerator();
   return e.MoveNext();
}
finally
{ 
    if (e is IDisposable)
        e.Dispose();
}

O, con genéricos:

using (IEnumerator<T> e = enumerable.GetEnumerator())
{
    return e.MoveNext();
}

Tienes razón en que no existe una respuesta perfecta.IEnumerable solo admite la iteración y no garantiza que la enumeración sea repetible.No puede averiguar si una enumeración contiene elementos sin llamar a MoveNext al menos una vez y, una vez que lo haya hecho, no puede garantizar que podrá reutilizar la enumeración:está permitido que IEnumerable.Reset arroje una NotSupportedException.De http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.reset.aspx:

"El método Reset se proporciona para la interoperabilidad COM.No necesariamente es necesario implementarlo;en cambio, el implementador puede simplemente lanzar una NotSupportedException".

Métodos de extensión como IEnumerable<T>.Count e IEnumerable<T>. Cualquier necesidad de llamar a MoveNext en secreto.Envoltorios útiles, pero no evite el hecho de que en los (raros) casos en los que una enumeración no admite Restablecer, podría tener un problema.

Una cosa con la que hay que tener cuidado con cualquiera de estos métodos es que no todas las enumeraciones se pueden revertir; por ejemplo, todas las implementaciones de System.Data.IDataReader solo se pueden ejecutar una vez.

En estos casos realmente no tienes un costo en un foreach bucle, siempre y cuando tenga en cuenta el hecho de que es posible que ni siquiera se realice un bucle una vez.

El primer método tiene una implementación simple del método de extensión vacía:http://signum.codeplex.com/SourceControl/changeset/view/25903#510468

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top