在 IEnumerable 上调用 Count 是否会迭代整个集合?
Does calling Count on IEnumerable iterate the whole collection?
考虑以下代码:
static IEnumerable<int> GetItems()
{
return Enumerable.Range(1, 10000000).ToArray(); // or: .ToList();
}
static void Main()
{
int count = GetItems().Count();
}
它会遍历所有 100 亿个整数并逐一计数,还是会使用数组的 Length
/ 列表的 Count
属性?
代码首先将所有整数放入数组(由于您的 .ToArray()
调用),然后 return 数组的长度(因为 all arrays implement ICollection
),其中实际代码调用。它不会将数组中的所有项目一一统计。
如果 IEnumerable
是 ICollection
,它将 return Count
属性。
这是source code:
public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null) throw Error.ArgumentNull("source");
ICollection<TSource> collectionoft = source as ICollection<TSource>;
if (collectionoft != null) return collectionoft.Count;
ICollection collection = source as ICollection;
if (collection != null) return collection.Count;
int count = 0;
using (IEnumerator<TSource> e = source.GetEnumerator())
{
checked
{
while (e.MoveNext()) count++;
}
}
return count;
}
数组实现了ICollection<T>
,所以不需要枚举
考虑以下代码:
static IEnumerable<int> GetItems()
{
return Enumerable.Range(1, 10000000).ToArray(); // or: .ToList();
}
static void Main()
{
int count = GetItems().Count();
}
它会遍历所有 100 亿个整数并逐一计数,还是会使用数组的 Length
/ 列表的 Count
属性?
代码首先将所有整数放入数组(由于您的 .ToArray()
调用),然后 return 数组的长度(因为 all arrays implement ICollection
),其中实际代码调用。它不会将数组中的所有项目一一统计。
如果 IEnumerable
是 ICollection
,它将 return Count
属性。
这是source code:
public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null) throw Error.ArgumentNull("source");
ICollection<TSource> collectionoft = source as ICollection<TSource>;
if (collectionoft != null) return collectionoft.Count;
ICollection collection = source as ICollection;
if (collection != null) return collection.Count;
int count = 0;
using (IEnumerator<TSource> e = source.GetEnumerator())
{
checked
{
while (e.MoveNext()) count++;
}
}
return count;
}
数组实现了ICollection<T>
,所以不需要枚举