В LINQ есть 2 способа подсчета числа: Count
и LongCount
. Практически единственная разница между этими двумя заключается в том, что первый возвращает int
, а второй возвращает long
.Есть ли практическая причина, по которой добавлен метод расширения LongCount от LINQ?
Непонятно, почему был добавлен второй метод. Кажется, что его единственным вариантом будет обработка перечислимых элементов из более чем 2B элементов. Это похоже на плохое решение для меня, по нескольким причинам:
Большинство BCL коллекций подкреплены одномерными массивами, которые имеют длины, которые гарантированно подходит в
int
. Пытаясь пройти мимо, подниметOverflowException
/OutOfMemoryException
.LongCount
is O (n) sinceIEnumerable
является ленивым. Если вы перечисляете элемент 3B, вы вызываете на негоLongCount
, а затем повторяете его снова (что вам нужно, если вы хотите использовать любое из значений), вы будете добавлять дополнительные 3B итерации, которые будут чрезвычайно медленным и скрывающим его от разработчика.Другие операции LINQ, такие как
ToArray
/ToList
, не поддерживают перечисления с элементами 2B + из-за (1).
Am Я-то здесь отсутствует, или есть более практическая причина, почему LongCount
был добавлен? Благодарю.
На основе исходного кода 'LongCount' просто выполняет итерацию через' IEnumerable' с помощью 'Enumerator.MoveNext', в то время как' Count' пытается использовать 'IEnumerable' для' ICollection' и использовать '' Count'', если кастинг был неуспешен, он будет итерации 'IEnumerable' так же, как' LongCount'. [Https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,d76b4b5d3fd67767](https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs, d76b4b5d3fd67767). Основываясь на этом «предположении» от @EricLipert, кажется очень логичным – Fabio
@Fabio, это просто оптимизация. Было бы семантически корректно для 'LongCount' проверять также' ICollection' и просто приводить результат к 'long', но' LongCount' не используется так сильно, поэтому поэтому они не беспокоились об этом. –