IEnumerable
Count()
和之间的主要区别是Length
什么?
Answers:
通过调用Count on,IEnumerable<T>
我假设您是指Count
on的扩展方法System.Linq.Enumerable
。 Length
不是IEnumerable<T>
.Net中的方法,而是.Net中的数组类型的属性,例如int[]
。
区别在于性能。该Length
属性保证是O(1)运算。Count
扩展方法的复杂度根据对象的运行时类型而有所不同。它将尝试ICollection<T>
通过Count
属性将类型转换为支持O(1)长度查找的几种类型。如果没有可用的,它将枚举所有项并计数,其复杂度为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
被实现为不支持O(1)计数的C#迭代器,因此该方法Count
必须枚举整个集合以确定其持续时间。
string[]
5-10个元素的短数组的情况下...那么您会建议Array.Length
性能吗?
Count()
数组实现的O(1)ICollection<T>
-但效率不如Length
直接使用。如果你已经知道它是一个数组,我会使用Length
不是效率,而是因为我认为这是更地道。同样,Count
对于任何编译时类型为的东西,我都会使用该属性ICollection<T>
。我会Count()
在编译时表达式的类型为时调用IEnumerable<T>
,即使我知道它实际上是幕后的数组。
System.Array
是一个更基础的类(类似于object
);但是在检查了MSDN之后,我看到它实现了几个“与集合相关”的接口。我是一名网络程序员,所以“ Count”起初在语义上更具意义(例如header
vs. div
HTML),但我理解您的观点,因为它string[]
在编译时显然是a的Length
。
while(list.Count() > 0)
一些带有添加/删除操作的逻辑。
小除了乔恩斯基特的评论。
这是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
有财产。)
use
获取Error
此方法使用的类?除了JScript文档,我似乎在MSDN上都找不到它。
长度是固定属性,例如一维数组或字符串。因此,永远不需要计数操作(多维数组的大小乘以所有维)。这里的O(1)运算意味着无论有多少个元素,检索时间始终是相同的。(与此相对)线性搜索为O(n)。
ICollections上的Count属性(例如List和List <T>)可以更改,因此必须在添加/删除操作上进行更新,或者在Collection更改后请求Count时进行更新。取决于对象的实现。
LINQ的Count()方法基本上在每次被调用时都会进行迭代(除非对象是ICollection类型,然后才请求ICollection.Count属性)。
请注意,IEnumerable通常不是已经定义的对象集合(例如列表,数组,哈希表等),而是链接到后台操作,这些后台操作在请求时会生成结果(称为延迟执行)。
通常,您有一个类似LINQ的SQL这样的语句(延迟执行的典型应用程序):
IEnumerable<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());
}
因此,当发出对太多部门负责人的警告时,.NET会经过人员四次,针对部门负责人对他们进行检查,按名称对他们进行排序,然后对结果对象进行计数。
仅当人员和部门是预设值集合,而不是查询自身时。
.Count() > 0
与.Any()
。
.Any()
比现在更有效.Count() > 0
吗?顺便说一句,Resharper总是抱怨.Count() > 0
。这就是为什么我满怀信心地提出来。
List<T>
没有Length属性-它具有Count属性。数组Length
虽然有。Count
在ICollection
和中指定ICollection<T>
(IList<T>
扩展)。