Ich habe diese Diskussion mit Kollegen, und wir können nicht herausfinden , was die Verwendung ist .Any
für jeden gegebenen List<>
, in C #.
Sie können die Gültigkeit eines Elements im Array wie folgt überprüfen:
if (MyList.Any()){ ...} //Returns true or false
Welches ist genau das gleiche wie
if (MyList.Count() != 0) { ... }
und ist viel häufiger, lesbar und klar über die Absicht der if
Aussage.
Am Ende waren wir mit diesem Gedanken festgefahren:
.Any()
verwendet werden kann, wird genauso gut funktionieren, ist aber weniger klar über die Absicht des Programmierers, und in diesem Fall sollte es nicht verwendet werden.
Aber wir haben das Gefühl, dass das nicht richtig sein kann. Wir müssen etwas vermissen.
Sind wir?
Any()
die weniger klar ist:Any()
scheint mir klarer zu sein, insbesondere bei einer Lambda-Erkrankung. Wenn ich den Code in meinem Kopf ins Englische übersetze,if(MyList.Count(o => o > 10) > 0)
wird "Ist die Anzahl der Artikel größer als 10 größer als 0?" währendif(MyList.Any(o => o > 10))
wird „Gibt es irgendwelche Gegenstände von mehr als 10?“Any
istExists
. Der Name Linq ist wahrscheinlich eher von Haskell und Python inspiriert, die ebenfalls alle Funktionen haben.Antworten:
Denken Sie daran, dass
Any
nicht auf einem operiertList
; Es wird auf einer ausgeführtIEnumerable
, die einen konkreten Typ darstellt, der eineCount
Eigenschaft haben kann oder nicht . Es ist wahr, dass es nicht unbedingt das Beste ist, um es auf einem zu verwendenList
, aber es ist definitiv nützlich am Ende einer LINQ-Abfrage. Und noch nützlicher als die Standalone-Version ist die Überschreibung, die ein Prädikat wie folgt annimmtWhere
. Es gibt nichts,List
was so praktisch oder aussagekräftig ist wie die PrädikaterweiterungsmethodeAny
.Wenn Sie
Count()
(die LINQ-Erweiterungsmethode für IEnumerable) anstelle vonCount
(die Eigenschaft onList
) verwenden, muss möglicherweise die gesamte Sequenz aufgelistet werden, wenn dies nicht durch die Erkennung einerCount
Eigenschaft des zugrunde liegenden Datentyps optimiert werden kann . Wenn Sie eine lange Folge haben, kann dies einen spürbaren Leistungseinbußen, wenn Sie nicht wirklich interessieren , was die Zählung ist, und möchte nur wissen , ob es irgendwelche Elemente in der Auflistung.quelle
Any()
mit einem Prädikat ist mehr ausdrucksvoller als Vergleich die Überschreibung desEnumerable.Count()
das braucht ein Prädikat mit 0 :)Exists
ist genauso bequem und ausdrucksstark wieAny
mit einem Prädikat. Die Verwendung vonCount != 0
property auf aList
ist normaler als die Verwendung vonAny()
. Es ist nur eine persönliche Präferenz. Ich habe mich auch bemüht_list_.Count()
,_list_.Count
in den Code meiner Gruppe zu wechseln . Es machte einen spürbaren Unterschied für mich.Es gibt eine Laufzeitdifferenz,
Count()
die O (n) sein kann, wobeiAny()
O (1) ist.quelle
Count()
wird auch nicht für unendliche Iteratoren anhalten, währendAny()
es nurMoveNext()
einmal aufgerufen werden muss.Any(Func<T>)
ist es O (n)List
ist die Leistung gleich, da die Erweiterung die Eigenschaft verwendet. True für alle Sammlungen, die dieICollection
Schnittstelle implementieren .Denken Sie daran, dass es die List.Count- Eigenschaft und dann die Enumerable.Count- Methode gibt.
In Ihrem Beispiel verwenden Sie die
Enumerable.Count()
Methode, die jedes einzelne Element der Aufzählung durchlaufen muss, um ein Ergebnis zurückzugeben. Das ist deutlich langsamer als ein Aufruf,Any()
der nur über das erste Element iterieren muss, falls es vorhanden ist.BEARBEITEN:
In den Kommentaren wurde zu Recht darauf hingewiesen, dass die
Enumerable.Count()
Erweiterungsmethode nicht alle Elemente durchlaufen muss, wenn festgestellt wird, dass es sich bei der Aufzählung auch um eine handeltICollection<T>
. Im Fall von a macht dieList<T>
Verwendung derCount
Eigenschaft oder Methode also keinen Unterschied.IEnumerable.Count- Quelle:
quelle
List<T>
der Leistungsunterschied vernachlässigbar. Verwenden Sie also einfach das, was Sie bevorzugen. Bei anderen Arten von IEnumerables können Sie jedoch nur zwischenCount()
(der Methode) wählen.Any()
In diesem Fall ist diesAny()
immer der eindeutige Gewinner für Ihren Anwendungsfall und sollte bevorzugt werden. Für das, was es wert ist, halte ich es fürAny()
gut lesbar und klar.Count()
hat die gleiche Komplexität wieCount
fürICollection
s, da die Erweiterungsmethode dann die Eigenschaft verwendet, anstatt zu iterieren.Eine überraschende Frage - ich finde die Absicht
list.Any()
, viel klarer zu sein als die Absicht vonlist.Count()!=0
.Absicht bedeutet: Wenn Sie einen Code gelesen haben (und ihn nicht selbst geschrieben haben), ist es völlig offensichtlich, was der Programmierer erreichen möchte und warum er so geschrieben hat, wie er ist? Wenn ein häufiges Problem unnötig komplex gelöst wird, wird man sofort misstrauisch und fragt sich, warum der Entwickler nicht den einfachen Weg gewählt hat. Sie sehen den Code durch und versuchen festzustellen, ob Sie etwas verpasst haben. Sie haben Angst, den Code zu ändern, weil Sie befürchten, dass ein Nebeneffekt fehlt, der zu unerwarteten Problemen führen kann.
Die Absicht der Verwendung der
Any()
Methode ist völlig klar - Sie möchten wissen, ob die Liste Elemente enthält oder nicht.Die Absicht des Ausdrucks
Count()!=0
dagegen ist für den Leser nicht offensichtlich. Es ist natürlich nicht schwer zu erkennen, dass der Ausdruck Ihnen sagt, ob die Liste leer ist oder nicht. Die Frage stellt sich, weil Sie es auf diese Weise schreiben, anstatt die Standardmethode zu verwenden. Warum benutzt duCount()
explizit? Wenn Sie wirklich brauchen nur zu wissen , ob es irgendwelche Elemente in einer Liste, warum tun Sie zuerst die ganze Liste zählen möchten? Sobald Sie 1 erreicht haben, haben Sie bereits Ihre Antwort. Wenn die Quelle ein Iterator über eine große (möglicherweise unendliche) Sammlung war oder in SQL übersetzt wird, kann dies die Leistung erheblich verbessern. Vielleicht besteht die explizite Verwendung von Count () darin, eine verzögerte Abfrage zur Ausführung zu zwingen oder einen Iterator zu durchlaufen?Aber die Quelle ist eigentlich ein
List<T>
WoCount()
ist O (1) und hat keine Nebenwirkungen. Aber wenn der Code von dieser Eigenschaft abhängtList<T>
, warum dann nicht dieCount
-Eigenschaft verwenden, die deutlicher anzeigt, dass Sie eine O (1) -Operation ohne Nebenwirkungen erwarten?Wie es geschrieben steht,
list.Count()!=0
tut es genau das Gleiche,list.Any()
außer es ist unnötig komplexer und die Absicht ist unklar.quelle
Count()
hat eine implizite Konvertierung, die ich vermeiden würde, aber es ist nicht unklar. Der Compiler kann es weg optimieren, was es nur zu einer unachtsamen Codierung macht.Vielleicht ist es nur das Wort?
Any
ist ein Adjektiv, das eigentlich gar nichts sagt. Wenn ich von Java komme, würde ich es so nennen, dass esisNonEmpty
ein Verb enthält. Ein SQL-Typ könnte es vorziehenEXISTS
. Passt aber vielleichtAny
am besten in das C # -System.Was auch immer das Wort Wahl sein mag, sobald Sie sich daran gewöhnt haben, muss es viel klarer sein. Würden Sie fragen, ob noch
more than zero
Bierflaschen übrig sind? Würden Sie erwarten, dassone or more
Personen mit der Zählung beginnen, bevor sie mit "Nein, gibt es nichtany
" antworten ?quelle
Any()
ist wirklich eine Abkürzung fürAny(o => true)