Eu estive discutindo isso com os colegas, e nós não poderíamos descobrir o que o uso é de .Any
para qualquer dado List<>
, em C #.
Você pode verificar a validade de um elemento na matriz como a seguinte declaração:
if (MyList.Any()){ ...} //Returns true or false
Qual é exatamente o mesmo que
if (MyList.Count() != 0) { ... }
e é muito mais comum, legível e claro sobre a intenção da if
declaração.
No final, ficamos presos a esse pensamento:
.Any()
pode ser usado, funcionará da mesma forma, mas é menos claro sobre a intenção do programador e, nesse caso, não deve ser usado.
Mas sentimos que isso não pode estar certo; devemos estar faltando alguma coisa.
Nós somos?
Any()
é menos clara:Any()
parece mais clara para mim, especialmente com uma condição lambda. A tradução do código para o inglês na minha cabeçaif(MyList.Count(o => o > 10) > 0)
se torna "O número de itens é maior que 10 e mais que 0?" enquantoif(MyList.Any(o => o > 10))
torna-se "Existem itens maiores que 10?"Any
sejaExists
. O nome Linq provavelmente é mais inspirado em Haskell e Python, que também possuem todas / todas as funções.Respostas:
Lembre-se de que
Any
não opera em umList
; opera em umIEnumerable
, que representa um tipo concreto que pode ou não ter umaCount
propriedade. É verdade que não é necessariamente a melhor coisa a ser usada em umList
, mas definitivamente é útil no final de uma consulta LINQ. E ainda mais útil que a versão autônoma é a substituição que requer um predicado da mesma formaWhere
. Não há nada embutidoList
que seja tão conveniente ou expressivo quanto oAny
método de extensão de predicado .Além disso, se você estiver usando
Count()
(o método de extensão LINQ para IEnumerable), em vez deCount
(a propriedade ativadaList
), pode ser necessário enumerar a sequência inteira se não puder otimizar isso, detectando que o tipo de dados subjacente possui umaCount
propriedade . Se você tiver uma sequência longa, isso pode ser um impacto perceptível no desempenho quando você realmente não se importa com o que é a contagem e só quer saber se há algum item na coleção.fonte
Any()
com um predicado é mais expressivo do que comparando a substituição daEnumerable.Count()
que leva um predicado com 0. :)Exists
é tão conveniente e expressivo quantoAny
, com um predicado. Usar aCount != 0
propriedade aList
é mais normal do que usarAny()
. É apenas preferência pessoal. Também passei pelo esforço de mudar_list_.Count()
para_list_.Count
o código do meu grupo. Isso fez uma diferença notável para mim.Há uma diferença no tempo de execução que
Count()
pode ser O (n) ondeAny()
é O (1).fonte
Count()
também não será interrompido por iteradores infinitos, enquantoAny()
será, pois ele precisará chamar apenasMoveNext()
uma vez.Any(Func<T>)
é O (n)List
, o desempenho é o mesmo porque a extensão usa a propriedade Verdadeiro para todas as coleções que implementam aICollection
interface.Na verdade, lembre-se de que existe a propriedade List.Count e, em seguida, o método Enumerable.Count .
No seu exemplo, você está usando o
Enumerable.Count()
método, que precisa percorrer todos os itens da enumeração para retornar um resultado. Isso é claramente mais lento que a chamada,Any()
que só precisa iterar sobre o primeiro item, se existir.EDITAR:
Nos comentários, foi indicado, com razão, que o
Enumerable.Count()
método de extensão não precisa percorrer todos os itens se detectar que o enumerável também é umICollection<T>
. Portanto, no caso de aList<T>
, usar aCount
propriedade ou o método não faz diferença.Fonte IEnumerable.Count :
fonte
List<T>
diferença de desempenho será insignificante. Então, basta usar o que você preferir. Mas para outros tipos de IEnumerables, você só escolhe entreCount()
(o método) eAny()
, nesse caso,Any()
sempre será o vencedor claro do seu caso de uso e deve ser o preferido. Pelo que vale, acho queAny()
é bastante legível e claro.Count()
tem a mesma complexidade queCount
paraICollection
s, pois o método de extensão usa a propriedade em vez de iterar.Uma pergunta surpreendente - acho que a intenção de
list.Any()
ser muito mais clara do que a intenção delist.Count()!=0
.Intenção significa: Se você leu o código de alguém (e não o escreveu), é completamente óbvio o que o programador deseja alcançar e por que ele foi escrito como está? Se um problema comum for resolvido de uma maneira desnecessariamente complexa, você imediatamente suspeita e se pergunta por que o desenvolvedor não usou a maneira simples. Você examina o código e tenta ver se perdeu alguma coisa. Você tem medo de alterar o código porque se preocupa com a falta de algum efeito colateral, e sua alteração pode causar problemas inesperados.
A intenção de usar o
Any()
método é completamente clara - você deseja saber se há algum elemento na lista ou não.A intenção da expressão,
Count()!=0
por outro lado, não é óbvia para o leitor. Obviamente, não é difícil ver que a expressão diz se a lista está vazia ou não. As perguntas surgem porque você a escreve dessa maneira específica, em vez de usar o método padrão. Por que você usaCount()
explicitamente? Se você realmente precisa apenas saber se há algum elemento em uma lista, por que deseja contar a lista inteira primeiro? Assim que você chegar a 1, você já tem sua resposta. Se a fonte fosse um iterador em uma coleção grande (talvez infinita) ou fosse traduzida para sql, isso poderia fazer uma grande diferença no desempenho. Então, talvez o uso explícito de Count () seja forçar uma consulta adiada para executar ou percorrer um iterador?Mas a fonte é realmente um
List<T>
ondeCount()
é O (1) e não tem efeitos colaterais. Mas se o código se baseia nessa propriedade deList<T>
, por que não usar aCount
propriedade-que indica mais claramente que você espera uma operação O (1) sem efeitos colaterais?Como está escrito,
list.Count()!=0
faz exatamente o mesmo quelist.Any()
exceto que é desnecessariamente mais complexo e a intenção não é clara.fonte
Count()
tem uma conversão implícita que eu evitaria usar, mas não é claro. O compilador pode otimizá-lo, o que apenas torna a codificação descuidada.Talvez seja apenas a palavra?
Any
é um adjetivo, sem realmente dizer nada. Vindo de Java, eu chamaria issoisNonEmpty
que contém um verbo. Um cara do SQL pode preferirEXISTS
. Mas talvezAny
se encaixe melhor no sistema C #.Qualquer que seja a escolha da palavra, uma vez que você se acostume, deve ser bem mais claro. Você perguntaria "
more than zero
Restam garrafas de cerveja". Você espera que asone or more
pessoas comecem a contá-las antes de responderem "Não, não existeany
"?fonte
Any()
é realmente um atalho paraAny(o => true)