He estado discutiendo esto con colegas, y no pudimos averiguar cuál es el uso de .Any
un determinado List<>
, en C #.
Puede verificar la validez de un elemento en la matriz como la siguiente declaración:
if (MyList.Any()){ ...} //Returns true or false
Que es exactamente lo mismo que
if (MyList.Count() != 0) { ... }
y es mucho más común, legible y claro sobre la intención de la if
declaración.
Al final, nos quedamos atrapados con este pensamiento:
.Any()
puede usarse, funcionará igual de bien, pero es menos claro acerca de la intención del programador y, en ese caso, no debe usarse.
Pero sentimos que esto no puede ser correcto; Debemos estar perdiendo algo.
¿Estamos?
Any()
es menos clara: meAny()
parece más clara, especialmente con una condición lambda. Traducir el código al inglés en mi cabeza, seif(MyList.Count(o => o > 10) > 0)
convierte en "¿Es el número de elementos mayor que 10 más que 0?" mientras que seif(MyList.Any(o => o > 10))
convierte en "¿Hay algún elemento mayor que 10?"Any
esExists
. El nombre de Linq probablemente esté más inspirado en Haskell y Python, que también tienen alguna / todas las funciones.Respuestas:
Tenga en cuenta que
Any
no funciona en unList
; opera en unIEnumerable
, que representa un tipo concreto que puede o no tener unaCount
propiedad. Es cierto que no es necesariamente lo mejor para usar en unList
, pero definitivamente es útil al final de una consulta LINQ. Y aún más útil que la versión independiente es la anulación que toma un predicado igual queWhere
. No hay nada incorporadoList
que sea tan conveniente o expresivo como elAny
método de extensión del predicado .Además, si está utilizando
Count()
(el método de extensión LINQ para IEnumerable), en lugar deCount
(la propiedad enList
), puede tener que enumerar toda la secuencia si no puede optimizar esto al detectar que su tipo de datos subyacente tiene unaCount
Propiedad . Si usted tiene una secuencia larga, esto puede ser un impacto de rendimiento notable cuando realmente no se preocupan por lo que el recuento es, y sólo quieren saber si hay alguna elementos de la colección.fuente
Any()
con un predicado es más expresivo que comparar la anulación deEnumerable.Count()
eso toma un predicado con 0. :)Exists
es tan conveniente y expresivo comoAny
, con un predicado. UsarCount != 0
propiedad en aList
es más normal que usarAny()
. Es solo preferencia personal. También he pasado por el esfuerzo de cambiar_list_.Count()
a_list_.Count
en el código de mi grupo. Hizo una diferencia notable para mí.Hay una diferencia de tiempo de ejecución que
Count()
puede ser O (n) dondeAny()
es O (1).fuente
Count()
tampoco se detendrá por iteradores infinitos, mientras queAny()
sí, ya que solo necesita llamarMoveNext()
una vez.Any(Func<T>)
is O (n)List
, el rendimiento es el mismo porque la extensión usa la propiedad. Verdadero para todas las colecciones que implementan laICollection
interfaz.En realidad, tenga en cuenta que existe la propiedad List.Count , y luego está el método Enumerable.Count .
En su ejemplo, está utilizando el
Enumerable.Count()
método, que tiene que recorrer cada elemento de la enumeración para obtener un resultado. Eso es claramente más lento que llamar,Any()
que solo necesita iterar sobre el primer elemento, si existe.EDITAR:
En los comentarios se señaló, con razón, que el
Enumerable.Count()
método de extensión no necesita iterar a través de todos los elementos si detecta que el enumerable también es unICollection<T>
. Entonces, en el caso de aList<T>
, el uso de laCount
propiedad o el método en realidad no hace la diferencia.Fuente IEnumerable.Count :
fuente
List<T>
la diferencia de rendimiento será insignificante. Así que solo usa lo que prefieras. Pero para otros tipos de IEnumerables, solo puede elegir entreCount()
(el método) yAny()
, en ese caso,Any()
siempre será el claro ganador para su caso de uso y debería preferirse. Por lo que vale, creo queAny()
es bastante legible y claro.Count()
tiene la misma complejidad queCount
paraICollection
s, ya que el método de extensión utiliza la propiedad en lugar de iterar.Una pregunta sorprendente: encuentro que la intención de
list.Any()
ser mucho más clara que la intención delist.Count()!=0
.Intención significa: si lees el código de alguien (y no lo escribiste tú mismo), ¿es completamente obvio lo que el programador quiere lograr y por qué lo escribió escrito así? Si un problema común se resuelve de una manera innecesariamente compleja, inmediatamente sospecha y se pregunta por qué el desarrollador no usó la forma simple. Miras el código e intentas ver si te has perdido algo. Tiene miedo de cambiar el código porque le preocupa que haya algún efecto secundario que le falte y cambiarlo puede causar problemas inesperados.
La intención de usar el
Any()
método es completamente clara: desea saber si hay elementos en la lista o no.La intención de la expresión,
Count()!=0
por otro lado, no es obvia para el lector. Por supuesto, no es difícil ver que la expresión te dice si la lista está vacía o no. Las preguntas surgen porque lo escribes de esta manera particular en lugar de usar el método estándar. ¿Por qué lo usasCount()
explícitamente? Si realmente sólo necesita saber si hay alguna elementos de una lista, ¿por qué desea contar toda la lista en primer lugar? Tan pronto como llegue a 1, ya tiene su respuesta. Si la fuente era un iterador sobre una colección grande (quizás infinita) o se traduce a sql, podría hacer una gran diferencia en cuanto al rendimiento. Entonces, ¿tal vez el uso explícito de Count () es forzar una consulta diferida para ejecutar o recorrer un iterador?Pero la fuente es en realidad un lugar
List<T>
dondeCount()
está O (1) y no tiene efectos secundarios. Pero si el código se basa en esta propiedad deList<T>
, ¿por qué no utilizar laCount
propiedad -que indica más claramente que espera una operación O (1) sin efectos secundarios?Como está escrito,
list.Count()!=0
hace exactamente lo mismo,list.Any()
excepto que es innecesariamente más complejo y la intención no está clara.fuente
Count()
tiene una conversión implícita que evitaría usar, pero no está claro. El compilador puede optimizarlo, lo que solo hace que la codificación sea descuidada.Tal vez es solo la palabra?
Any
es un adjetivo, en realidad no dice nada. Viniendo de Java, lo llamaríaisNonEmpty
que contiene un verbo. Un chico SQL podría preferirEXISTS
. Pero quizásAny
encaja mejor en el sistema C #.Cualquiera sea la palabra que elija, una vez que se acostumbre a ella, debe ser mucho más clara. ¿Preguntarías "
more than zero
quedan botellas de cerveza"? ¿Esperarías que lasone or more
personas empiecen a contarlos antes de que respondan "No, no hayany
"?fuente
Any()
es realmente un atajo paraAny(o => true)