Byłem omawiania tego z kolegami, a nie mogliśmy dowiedzieć się, co ma zastosowanie .Any
dla danego List<>
, w języku C #.
Możesz sprawdzić poprawność elementu w tablicy, podobnie jak następująca instrukcja:
if (MyList.Any()){ ...} //Returns true or false
Który jest dokładnie taki sam jak
if (MyList.Count() != 0) { ... }
i jest znacznie bardziej powszechny, czytelny i jasny na temat intencji tego if
stwierdzenia.
W końcu utknęliśmy z tą myślą:
.Any()
może być używany, będzie działał równie dobrze, ale nie jest jasne, co do intencji programisty, i w takim przypadku nie należy go używać.
Ale czujemy, że to nie może być prawda; coś nam brakuje.
Jesteśmy?
Any()
jest mniej jasne:Any()
wydaje mi się bardziej jasne, szczególnie w przypadku lambda. Tłumaczenie kodu na angielski w mojej głowieif(MyList.Count(o => o > 10) > 0)
brzmi: „Czy liczba pozycji większa niż 10 jest większa niż 0?” mając naif(MyList.Any(o => o > 10))
myśli „Czy są jakieś przedmioty większe niż 10?”Any
toExists
. Nazwa Linq jest prawdopodobnie bardziej zainspirowana przez Haskell i Python, które mają również dowolne / wszystkie funkcje.Odpowiedzi:
Pamiętaj, że
Any
nie działa naList
; działa naIEnumerable
, który reprezentuje konkretny typ, który może miećCount
właściwość lub nie . To prawda, że niekoniecznie jest to najlepsza rzecz do użyciaList
, ale na pewno przydaje się na końcu zapytania LINQ. Jeszcze bardziej przydatne niż wersja autonomiczna jest zastąpienie, które podobnie jak predykatWhere
. Nie ma nic wbudowanegoList
, co byłoby tak wygodne lub wyraziste, jakAny
metoda rozszerzenia predykatu .Ponadto, jeśli używasz
Count()
(metoda rozszerzenia LINQ dla IEnumerable) zamiastCount
(właściwość onList
), może być konieczne wyliczenie całej sekwencji, jeśli nie można jej zoptymalizować, wykrywając, że Twój typ danych maCount
właściwość . Jeśli masz długą sekwencję, może to być zauważalny spadek wydajności, gdy tak naprawdę nie zależy ci na tym, co się liczy, i po prostu chcesz wiedzieć, czy w kolekcji są jakieś elementy.źródło
Any()
z predykatem jest bardziej ekspresyjny niż porównywanie tego,Enumerable.Count()
co ma predykat z 0. :)Exists
jest tak samo wygodny i wyrazisty jakAny
z predykatem. UżywanieCount != 0
właściwości naList
jest bardziej normalne niż używanieAny()
. To tylko osobiste preferencje. Ja również przeszedł wysiłku zmienia_list_.Count()
się_list_.Count
w kodzie mojej grupy. To zrobiło dla mnie zauważalną różnicę.Różnica czasu pracy
Count()
może wynosić O (n), gdzieAny()
jest O (1).źródło
Count()
nie zatrzyma się także dla nieskończonych iteratorów, podczas gdyAny()
będzie, ponieważ wystarczy zadzwonićMoveNext()
tylko raz.Any(Func<T>)
jest O (n)List
wydajność jest taka sama, ponieważ rozszerzenie korzysta z właściwości. Prawda dla wszystkich kolekcji implementującychICollection
interfejs.Należy pamiętać, że istnieje właściwość List.Count , a następnie metoda Enumerable.Count .
W twoim przykładzie używasz
Enumerable.Count()
metody, która musi iterować każdy element wyliczenia, aby zwrócić wynik. Jest to wyraźnie wolniejsze niż sprawdzanie,Any()
które musi powtarzać tylko pierwszy element, jeśli istnieje.EDYTOWAĆ:
W komentarzach wskazano słusznie, że
Enumerable.Count()
metoda rozszerzenia nie musi iterować wszystkich elementów, jeśli wykryje, że wyliczenie również się zdarzaICollection<T>
. Tak więc w przypadku aList<T>
użycieCount
właściwości lub metody nie robi żadnej różnicy.Źródło IEnumerable.Count :
źródło
List<T>
różnicą wydajności będzie znikoma. Więc po prostu użyj tego, co wolisz. Ale w przypadku innych typów IEnumerables możesz jedynie wybierać pomiędzyCount()
(metodą),Any()
aw takim przypadkuAny()
zawsze będzie wyraźnym zwycięzcą dla twojego przypadku użycia i powinno być preferowane. Co do tego, co jest warte, myślę, żeAny()
jest dość czytelny i jasny.Count()
ma taką samą złożoność jakCount
dlaICollection
s, ponieważ metoda rozszerzenia używa właściwości zamiast iteracji.Zaskakujące pytanie - uważam, że intencja jest o
list.Any()
wiele jaśniejsza niż intencjalist.Count()!=0
.Cel: oznacza, że jeśli czytasz czyjś kod (a sam go nie napisałeś), czy jest całkowicie oczywiste, co programista chce osiągnąć i dlaczego napisał tak, jak jest? Jeśli wspólny problem zostanie rozwiązany w niepotrzebnie skomplikowany sposób, natychmiast podejrzewasz i zastanawiasz się, dlaczego programista nie zastosował prostej metody. Przeglądasz kod i próbujesz sprawdzić, czy coś przeoczyłeś. Boisz się zmienić kod, ponieważ obawiasz się, że brakuje jakiegoś efektu ubocznego, a jego zmiana może spowodować nieoczekiwane problemy.
Cel użycia tej
Any()
metody jest całkowicie jasny - chcesz wiedzieć, czy są jakieś elementy na liście, czy nie.Z
Count()!=0
drugiej strony cel wyrażenia nie jest oczywisty dla czytelnika. Oczywiście nietrudno zauważyć, że wyrażenie informuje, czy lista jest pusta, czy nie. Pytania powstają, ponieważ piszesz je w ten konkretny sposób, zamiast używać standardowej metody. Dlaczego używaszCount()
jawnie? Jeśli naprawdę potrzebujesz tylko wiedzieć, czy na liście znajdują się jakieś elementy, dlaczego najpierw chcesz policzyć całą listę? Jak tylko osiągniesz 1, masz już swoją odpowiedź. Jeśli źródło było iteratorem dużej (być może nieskończonej) kolekcji lub zostało przetłumaczone na sql, mogłoby to mieć duży wpływ na wydajność. Może więc jawnym zastosowaniem Count () jest wymuszenie wykonania odroczonego zapytania w celu wykonania iteratora?Ale źródło jest w rzeczywistości
List<T>
gdzieCount()
jest O (1) i nie ma skutków ubocznych. Ale jeśli kod opiera się na tej właściwościList<T>
, to dlaczego nie użyćCount
właściwości, która wyraźniej wskazuje, że oczekujesz operacji O (1) bez efektów ubocznych?Jak napisano,
list.Count()!=0
robi dokładnie to samo, colist.Any()
poza tym, że jest niepotrzebnie bardziej skomplikowane, a intencja jest niejasna.źródło
Count()
ma domyślną konwersję, której chciałbym uniknąć, ale nie jest niejasne. Kompilator może go zoptymalizować, co czyni go nieostrożnym kodowaniem.Może to tylko słowo?
Any
jest przymiotnikiem, tak naprawdę nic nie mówiąc. Pochodzę z Javy, nazwałbym toisNonEmpty
czasownikiem. Facet z SQL może preferowaćEXISTS
. Ale możeAny
najlepiej pasuje do systemu C #.Niezależnie od wyboru słowa, po przyzwyczajeniu się do niego, musi być znacznie jaśniejsze. Czy zapytasz „Czy zostały
more than zero
butelki piwa”. Czy spodziewałbyś się, żeone or more
osoby zaczną je liczyć, zanim odpowiedzą „Nie, nie maany
”?źródło
Any()
to naprawdę skrót doAny(o => true)