咨询区
-
balalakshmi:
请问 Linq 的扩展方法 Count()
和 Length
有什么不同 ?.
回答区
-
JaredPar:
Linq 中的 Count()
一般指的是 System.Linq.Enumerable
下的 Count 方法,而 Length
既不是方法也不属于 IEnumerable<T>
,它只是 Array 下的一个固定属性,比如:int[],string[]
。
这里的主要不同点在于性能,Length
属性的时间复杂度为 O(1),而 Count()
方法的时间复杂度则依赖于你需要操作对象的运行时类型,如果你在 ICollection<T>
上进行 Count()
,那么它的复杂度为 O(1),这是因为它会直接读取该集合的 Count 属性,如果可迭代集合没有类似直取属性那么将会迭代集合中的所有项,此时复杂度为 O(N)。
具体可参考 Count()
源代码。
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;
}
可测试案例如下:
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)
点评区
这个问题或许困扰了很多初学的朋友,JaredPar大佬解答的非常好,尤其在 Count()
源码面前了无秘密,学习了。