Между чем основные отличия IEnumerable
Count()
и Length
?
Вызывая Count на IEnumerable
, я предполагаю, что вы имеете в виду метод расширения Count
на System.Linq.Enumerable
. Length
- это не метод для IEnumerable
, а скорее свойство для типов массивов в .Net, таких как int []
.
Разница в производительности. Свойство Длина
гарантированно является операцией O (1). Сложность метода расширения Count
зависит от типа среды выполнения объекта. Он попытается выполнить приведение к нескольким типам, которые поддерживают поиск длины O (1), например ICollection
, через свойство Count
. Если ни один из них недоступен, он перечислит все элементы и посчитает их со сложностью O (N).
Например
int[] list = CreateSomeList();
Console.WriteLine(list.Length); // O(1)
IEnumerable<int> e1 = list;
Console.WriteLine(e1.Count()); // O(1)
IEnumerable<int> e2 = list.Where(x => x <> 42);
Console.WriteLine(e2.Count()); // O(N)
Значение e2
реализовано как итератор C #, который не поддерживает подсчет O (1), и, следовательно, метод Count
должен перечислить всю коллекцию для определения как долго это
Небольшое дополнение к комментарию Джона Скита .
Вот исходный код метода расширения Count ()
:
.NET 3:
public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
ICollection<TSource> is2 = source as ICollection<TSource>;
if (is2 != null)
{
return is2.Count;
}
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
}
}
return num;
}
.NET 4:
public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
ICollection<TSource> is2 = source as ICollection<TSource>;
if (is2 != null)
{
return is2.Count;
}
ICollection is3 = source as ICollection;
if (is3 != null)
{
return is3.Count;
}
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
}
}
return num;
}