que - ¿Qué es una pieza de código sólida, elegante y reutilizable para determinar si un IEnumerable está vacío en.NET?
system collections objectmodel (5)
Estoy tratando de encontrar el fragmento de código más reutilizable, pero elegante, posible para determinar si un IEnumerable. En el ideal, esta debería ser una función a la que pueda llamar absolutamente 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 hasta ahora, mi pensamiento actual es que no existe una respuesta perfecta, ya que un IEnumerable puede encapsular técnicamente 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.
Edit: Wow, no puedo creer que no supiera sobre IEnumerable.Any. Sabía que existía, pero nunca me molesté en comprobar qué hacía. Deja que esto sea una lección. Lee la documentación. El hecho de que un nombre de método no implique que hace lo que quiere, no significa que no hace lo que usted quiere.
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 hay una respuesta perfecta. IEnumerable solo es compatible con 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 pueda reutilizar la enumeración: se permite que IEnumerable.Reset arroje una excepción NotSupportedException. De http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.reset.aspx :
"El método Restablecer se proporciona para la interoperabilidad COM. No necesariamente debe implementarse, en cambio, el implementador puede simplemente lanzar una NotSupportedException".
Los métodos de extensión como IEnumerable <T> .Count e IEnumerable <T>. Cualquier necesidad de llamar a MoveNext debajo de las cubiertas. Envolturas útiles, pero no evite el hecho de que en los casos (raros) en que una enumeración no es compatible con Restablecer, podría tener un problema.
Una cosa a tener cuidado con cualquiera de estos métodos es que no todas las enumeraciones se pueden retrotraer, por ejemplo, todas las implementaciones de System.Data.IDataReader solo se pueden ejecutar una vez.
En estos casos, realmente no tiene un costo en un bucle foreach
, siempre y cuando tenga en cuenta el hecho de que puede que ni siquiera se repita 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
!enumerable.Any()
Intentará agarrar el primer elemento solamente.
Para ampliar cómo / por qué funciona esto, cualquiera determina si alguno de los componentes de un IEnumerable
coincide con una función determinada, si no se proporciona ninguno, entonces cualquier componente tendrá éxito, lo que significa que la función devolverá verdadero si existe un elemento en el enumerable.