IEnumerable
Count()
和 Length
有什么关键区别?
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
必须枚举整个集合来确定其长度。对Jon Skeet的评论的小补充。
这是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;
}
ICollection
зұ»еһӢпјҲеӣ дёәе®ғд№ҹе…·жңүCount
еұһжҖ§пјүгҖӮ - Jon SkeetIEnumerable<Person> deptLeaders =
from p in persons
join d in departments
on p.ID equals d.LeaderID
orderby p.LastName, p.FirstName
select p;
if (deptLeaders.Count() > 0)
{
ReportNumberOfDeptLeaders(deptLeaders.Count());
if (deptLeaders.Count() > 20)
WarnTooManyDepartmentLeaders(deptLeaders.Count());
}
.Count() > 0
和 .Any()
是相同的。 - jedmao.Any()
难道不比使用.Count() > 0
更有效吗?顺便说一句,Resharper总是会抱怨.Count() > 0
。这就是我有把握提出这个问题的原因。 - jedmao
List<T>
没有 Length 属性,而是有一个名为 Count 的属性。不过,数组有 Length 属性。Count
属性在ICollection
和ICollection<T>
中定义(IList<T>
继承自这两个接口)。 - Jon Skeetstring[]
数组的情况下,你们建议使用Array.Length
来提高性能吗? - one.beat.consumerICollection<T>
,那么使用Count()
仍然是O(1),但它比直接使用Length
要低效。如果您已经知道它是一个数组,我会使用Length
而不是为了效率,而是因为我认为这更符合惯用法。同样,对于任何具有编译时类型ICollection<T>
的内容,我会使用Count
属性。当编译时表达式的类型为IEnumerable<T>
时,即使我知道其背后实际上是一个数组,我也会调用Count()
。 - Jon SkeetSystem.Array
是一个更基本的类(类似于object
); 但在查看MSDN后,我发现它实现了几个“集合相关”的接口。我是一个Web程序员,所以“Count”一开始更有语义意义(就像HTML中的header
与div
),但我理解你的观点,因为它在编译时明确是一个string[]
,所以Length
更有意义。 - one.beat.consumerwhile(list.Count() > 0)
执行一些包含添加/移除操作的逻辑。 - Johnny_D