J'ai discuté avec des collègues, et nous ne pouvions pas comprendre ce que l'utilisation est .Any
pour tout donné List<>
, en C #.
Vous pouvez vérifier la validité d'un élément du tableau comme ci-dessous:
if (MyList.Any()){ ...} //Returns true or false
Qui est exactement le même que
if (MyList.Count() != 0) { ... }
et est beaucoup plus commun, lisible et clair sur l'intention de la if
déclaration.
En fin de compte, nous étions coincés avec cette pensée:
.Any()
peut être utilisé, fonctionnera tout aussi bien, mais est moins clair sur l'intention du programmeur, et dans ce cas, il ne devrait pas être utilisé.
Mais nous pensons que cela ne peut pas être juste; nous devons manquer quelque chose.
Sommes nous?
Any()
est moins claire:Any()
me semble plus claire, surtout avec une condition lambda. Traduire le code en anglais dans ma têteif(MyList.Count(o => o > 10) > 0)
devient "Le nombre d'éléments supérieur à 10 est-il supérieur à 0?" alors queif(MyList.Any(o => o > 10))
devient "Y a-t-il des objets supérieurs à 10?"Any
estExists
. Le nom Linq est probablement plus inspiré de Haskell et Python, qui ont également toutes les fonctions.Réponses:
Gardez à l'esprit que
Any
cela ne fonctionne pas sur unList
; il opère sur unIEnumerable
, qui représente un type concret qui peut ou non avoir uneCount
propriété. Il est vrai que ce n’est pas forcément la meilleure chose à utiliser sur unList
, mais cela est très utile à la fin d’une requête LINQ. Et même plus utile que la version autonome est le remplacement qui prend un prédicat commeWhere
. Il n'y a rien de plus intégréList
qui soit aussi pratique ou expressif que laAny
méthode d'extension de prédicat .De même, si vous utilisez
Count()
(la méthode d'extension LINQ pour IEnumerable) plutôt queCount
(la propriété activéeList
), il peut être nécessaire d'énumérer la séquence entière s'il ne peut pas l'optimiser en détectant que votre type de données sous-jacent a uneCount
propriété. . Si vous avez une longue séquence, cela peut avoir un impact notable sur les performances lorsque vous ne vous souciez pas vraiment du nombre, et que vous voulez simplement savoir s'il y a des éléments dans la collection.la source
Any()
avec un prédicat est plus expressif que de comparer le dépassement deEnumerable.Count()
qui prend un prédicat avec 0.Exists
est aussi pratique et expressif queAny
, avec un prédicat. Utiliser uneCount != 0
propriété sur unList
est plus normal que d’utiliserAny()
. C'est juste une préférence personnelle. Je suis aussi passé par l'effort de changer_list_.Count()
pour_list_.Count
dans le code de mon groupe. Cela a fait une différence notable pour moi.Il y a une différence de temps d'exécution qui
Count()
peut être O (n) oùAny()
est O (1).la source
Count()
également ne s'arrêtera pas pour les itérateurs infinis, tandis que leAny()
sera, puisqu'il suffit d'appelerMoveNext()
une fois.Any(Func<T>)
is O (n)List
, les performances sont identiques car l'extension utilise la propriété. Vrai pour toutes les collections implémentant l'ICollection
interface.En fait, gardez à l'esprit qu'il existe la propriété List.Count , puis la méthode Enumerable.Count .
Dans votre exemple, vous utilisez la
Enumerable.Count()
méthode, qui doit parcourir chaque élément de l'énumération pour renvoyer un résultat. C’est clairement plus lent que d’appelerAny()
qui ne doit parcourir que le premier élément, s’il existe.MODIFIER:
Dans les commentaires, il a été souligné, à juste titre, que la
Enumerable.Count()
méthode d’extension n’a pas besoin de parcourir tous les éléments si elle détecte que l’énumérable est également unICollection<T>
. Donc, dans le cas d'unList<T>
, utiliser laCount
propriété ou la méthode ne fait pas de différence.Source IEnumerable.Count :
la source
List<T>
la différence de performance sera négligeable. Alors, utilisez ce que vous préférez. Mais pour les autres types de IEnumerables, vous ne pouvez choisir qu'entreCount()
(la méthode) etAny()
, et dans ce cas,Any()
sera toujours le gagnant gagnant de votre cas d'utilisation et devrait être préféré. Pour ce que ça vaut, je pense queAny()
c'est assez lisible et clair.Count()
a la même complexité queCount
pourICollection
s, puisque la méthode d’extension utilise alors la propriété au lieu d’itérer.Une question surprenante - Je trouve l’intention d’
list.Any()
être beaucoup plus claire que l’intention delist.Count()!=0
.Intention signifie: si vous lisez le code de quelqu'un (et que vous ne l'avez pas écrit vous-même), est-il tout à fait évident que le programmeur veut réaliser et pourquoi il est écrit comme il est? Si un problème courant est résolu de manière inutilement complexe, vous êtes immédiatement suspicieux et vous vous demandez pourquoi le développeur n'a pas utilisé la méthode la plus simple. Vous parcourez le code et essayez de voir si vous avez oublié quelque chose. Vous avez peur de modifier le code car vous craignez que certains effets indésirables ne vous fassent pas défaut et que vous risquez de provoquer des problèmes inattendus.
L'intention d'utiliser la
Any()
méthode est tout à fait claire - vous voulez savoir s'il y a des éléments dans la liste ou non.L'intention de l'expression
Count()!=0
en revanche n'est pas évidente pour le lecteur. Bien entendu, il n’est pas difficile de voir que l’expression vous indique si la liste est vide ou non. Les questions se posent parce que vous écrivez de cette manière particulière plutôt que d'utiliser la méthode standard. Pourquoi utilisez-vousCount()
explicitement? Si vous avez vraiment besoin de savoir s'il y a des éléments dans une liste, pourquoi voulez-vous d'abord compter toute la liste? Dès que vous atteignez 1, vous avez déjà votre réponse. Si la source était un itérateur d'une grande collection (peut-être infinie) ou si elle était traduite en SQL, cela pourrait faire une grande différence en termes de performances. Alors peut-être que l'utilisation explicite de Count () consiste à forcer une requête différée à s'exécuter ou à traverser un itérateur?Mais la source est en fait un
List<T>
oùCount()
est O (1) et n'a pas d'effets secondaires. Mais si le code s'appuie sur cette propriété deList<T>
, alors pourquoi ne pas utiliser laCount
propriété-qui indique plus clairement que vous attendez une opération O (1) sans effets secondaires?Comme il est écrit,
list.Count()!=0
fait exactement la même chose,list.Any()
sauf que c'est inutilement plus complexe et que l'intention n'est pas claire.la source
Count()
a une conversion implicite que je voudrais éviter d'utiliser, mais ce n'est pas flou. Le compilateur peut l'optimiser à distance, ce qui ne fait que coder sans précaution.Peut-être que c'est juste le mot?
Any
est un adjectif, ne dit vraiment rien. Venant de Java, je l'appelleraisisNonEmpty
qui contient un verbe. Un gars de SQL pourrait préférerEXISTS
. Mais peut-êtreAny
convient-il mieux au système C #.Quel que soit le mot choisi, une fois que vous vous y habiterez, il doit être plus clair. Souhaitez-vous demander "Est-ce qu'il
more than zero
reste des bouteilles de bière"? Vous attendriez-vous à ce que desone or more
personnes commencent à les compter avant de répondre «non, il n'y en a pasany
»?la source
Any()
c'est vraiment un raccourci pourAny(o => true)