Pracując z kolekcją, mam dwa sposoby uzyskania liczby obiektów; Count
(właściwość) i Count()
(metoda). Czy ktoś wie, jakie są kluczowe różnice?
Mogę się mylić, ale zawsze używam tej Count
właściwości w jakichkolwiek instrukcjach warunkowych, ponieważ zakładam, że Count()
metoda wykonuje jakieś zapytanie względem kolekcji, gdzie Count
musiało być już przypisane przed moim „pobieraniem”. Ale to przypuszczenie - nie wiem, czy jeśli się mylę, wpłynie to na wydajność.
EDYCJA: Więc z ciekawości Count()
wyrzuci wyjątek, jeśli kolekcja jest pusta? Ponieważ jestem prawie pewien, że Count
właściwość po prostu zwraca 0.
.
operator do czegoś, co ma wartość null.Odpowiedzi:
Dekompilacja źródła dla
Count()
metody rozszerzenia ujawnia, że sprawdza, czy obiekt jestICollection
(generyczny lub inny), a jeśli tak, po prostu zwracaCount
właściwość bazową :Tak więc, jeśli twój kod uzyskuje dostęp
Count
zamiast wywoływaćCount()
, możesz ominąć sprawdzanie typu - teoretyczna korzyść z wydajności, ale wątpię, czy byłaby zauważalna!// System.Linq.Enumerable public static int Count<TSource>(this IEnumerable<TSource> source) { checked { if (source == null) { throw Error.ArgumentNull("source"); } ICollection<TSource> collection = source as ICollection<TSource>; if (collection != null) { return collection.Count; } ICollection collection2 = source as ICollection; if (collection2 != null) { return collection2.Count; } int num = 0; using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { num++; } } return num; } }
źródło
Count()
nie sprawdzaICollection
interfejsu nieogólnego . Zostało to dodane tylko w .NET 4. Zarówno wersja 3.5, jak i 4 sprawdzająICollection<T>
interfejs ogólny .Wydajność to tylko jeden z powodów, dla których warto wybrać jedną z nich. Wybór
.Count()
oznacza, że Twój kod będzie bardziej ogólny. Zdarzały się sytuacje, w których refaktoryzowałem kod, który nie tworzył już kolekcji, ale zamiast tego coś bardziej ogólnego, jak IEnumerable, ale inny kod zepsuł się w wyniku, ponieważ zależał od.Count
i musiałem go zmienić.Count()
. Gdybym chciał używać go.Count()
wszędzie, kod prawdopodobnie byłby łatwiejszy do ponownego wykorzystania i utrzymania. Zazwyczaj najlepszym rozwiązaniem jest skorzystanie z bardziej ogólnych interfejsów, jeśli możesz sobie z tym poradzić. Przez bardziej ogólny rozumiem prostszy interfejs, który jest zaimplementowany przez więcej typów, a tym samym zapewnia większą zgodność między kodem.Nie mówię, że
.Count()
jest lepsze, mówię tylko, że istnieją inne kwestie, które dotyczą bardziej ponownego wykorzystania kodu, który piszesz.źródło
.Count()
Metoda może być na tyle sprytny, lub wie o rodzaju produktu, a jeśli tak, to może skorzystać z podstawowych.Count
własności.Ale może nie.
Powiedziałbym, że można bezpiecznie założyć, że jeśli kolekcja ma
.Count
samą właściwość, będzie to najlepszy wybór, jeśli chodzi o wydajność.Jeśli
.Count()
metoda nie wie o kolekcji, wyliczy ją, co będzie operacją O (n).źródło
Count
właściwości mogłoby być lepsze, aleCount()
tworzenie metod przy użyciuICollection<T>.Count
jest trochę udokumentowane tutaj: msdn.microsoft.com/en-us/library/bb338038(v=vs.110).aspxCount()
metoda jest metodą rozszerzającą, która iteruje każdy element anIEnumerable<>
i zwraca liczbę elementów. Jeśli instancjaIEnumerable
jest faktycznie aList<>
, jest więc zoptymalizowana pod kątem zwracaniaCount
właściwości zamiast iterowania wszystkich elementów.źródło
Count()
istnieje jako metoda rozszerzenia z LINQ -Count
jest właściwością naList
s, rzeczywistych obiektach kolekcji .NET.Jako taki,
Count()
prawie zawsze będzie wolniejszy, ponieważ wylicza kolekcję / obiekt podlegający zapytaniom. Na liście, kolejce, stosie itpCount
. Użyj . Lub dla tablicy -Length
.źródło
Wersja skrócona: Jeśli masz wybór między
Count
właściwością a plikiemCount()
metodą, zawsze wybieraj właściwość.Różnica polega głównie na wydajności operacji. Wszystkie kolekcje BCL, które ujawniają
Count
właściwość, robią to w sposób O (1). JednakCount()
metoda ta może i często będzie kosztować O (N). Istnieje kilka testów, które można spróbować doprowadzić do O (1) dla niektórych implementacji, ale w żadnym wypadku nie jest to gwarantowane.źródło
Jeśli istnieje właściwość
Count
lubLength
, zawsze powinieneś preferować tęCount()
metodę niż metodę, która generalnie iteruje całą kolekcję, aby policzyć liczbę elementów w niej zawartych. Wyjątkami byłyby sytuacje, w którychCount()
metoda jest skierowana przeciwko źródłu LINQ to SQL lub LINQ to Entities, na przykład w takim przypadku wykona zapytanie zliczające względem źródła danych. Nawet wtedy, jeśli istniejeCount
nieruchomość, wolisz ją, ponieważ prawdopodobnie ma mniej pracy.źródło
Ta
Count()
metoda jest metodą LINQ, która działa na dowolnymIEnumerable<>
. Można oczekiwać, żeCount()
metoda będzie iterować całą kolekcję, aby znaleźć liczbę, ale uważam, że kod LINQ faktycznie zawiera pewne optymalizacje, aby wykryć, czy istnieje właściwość Count, a jeśli tak, użyj jej.Więc obaj powinni robić prawie identyczne rzeczy. Właściwość Count jest prawdopodobnie nieco lepsza, ponieważ nie ma tam potrzeby sprawdzania typu.
źródło