在处理集合时,我知道有两种方式可以获取对象的数量:Count
(属性)和Count()
(方法)。有没有人知道它们之间的关键区别?
我可能错了,但我总是在任何条件语句中使用Count
属性,因为我假设Count()
方法针对集合执行某种查询,而Count
必须在我“获取”之前已经被分配。但这只是一个猜测 - 如果我错了,我不知道性能是否会受到影响。
编辑:那么出于好奇,如果集合为空,Count()
会抛出异常吗?因为我很确定Count
属性只返回0。
在处理集合时,我知道有两种方式可以获取对象的数量:Count
(属性)和Count()
(方法)。有没有人知道它们之间的关键区别?
我可能错了,但我总是在任何条件语句中使用Count
属性,因为我假设Count()
方法针对集合执行某种查询,而Count
必须在我“获取”之前已经被分配。但这只是一个猜测 - 如果我错了,我不知道性能是否会受到影响。
编辑:那么出于好奇,如果集合为空,Count()
会抛出异常吗?因为我很确定Count
属性只返回0。
反编译 Count()
扩展方法的源代码会发现它测试对象是否是一个 ICollection
(一般或泛型),如果是,则简单地返回底层的 Count
属性:
因此,如果您的代码访问 Count
而不是调用 Count()
,则可以绕过类型检查 - 这理论上会有性能提升,但我怀疑这不会有明显的效果!
// System.Linq.Enumerable
public static int Count<TSource>(this IEnumerable<TSource> source)
{
checked
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
ICollection<TSource> collection = source as ICollection<TSource>;
if (collection != null)
{
return collection.Count;
}
ICollection collection2 = source as ICollection;
if (collection2 != null)
{
return collection2.Count;
}
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
}
}
return num;
}
}
Count()
方法不会检查非泛型的ICollection
接口,这个功能只在.NET 4中添加。无论是3.5还是4,都会检查泛型的ICollection<T>
接口。 - thecoop性能只是选择其中一种方法的原因,而不是唯一的原因。 选择 .Count()
意味着您的代码将更加通用。 我曾经遇到过这样的情况,我重构了一些代码,并非产生集合,而是像 IEnumerable 这样更通用的东西,但由于依赖于 .Count
的其他代码导致代码出现故障,因此我不得不将其更改为 .Count()
。如果我在所有地方使用 .Count()
,则代码可能会更具可重用性和可维护性。通常,如果可以做到这一点,最好选择使用更通用的接口。 通过更通用,我指的是实现更多类型的简单接口,从而在代码之间获得更大的兼容性。
我并不是说 .Count()
更好,我只是说还有其他考虑因素,涉及到您正在编写的代码的可重用性。
.Count()
方法可能很聪明,或者知道查询的类型,如果是这样的话,它可能会使用底层的.Count
属性。.Count
属性,那么在性能方面这将是最好的选择。.Count()
方法不知道集合的情况,它将枚举整个集合,这将是一个O(n)的操作。Count
属性会更好,但是使用 Count()
方法来使用 ICollection<T>.Count
在这里有一定的文档说明:https://msdn.microsoft.com/zh-cn/library/bb338038(v=vs.110).aspx - nawfalCount()
方法是适用于任何 IEnumerable<>
的 LINQ 方法。 你可能会认为 Count()
方法会遍历整个集合来查找计数,但我相信 LINQ 代码实际上有一些优化措施来检测是否存在 Count 属性,如果存在,则使用它。Count()
方法是一个扩展方法,它遍历IEnumerable<>
的每个元素并返回元素数量。如果IEnumerable
实例实际上是一个List<>
,那么它会优化返回Count
属性而不是遍历所有元素。
Count()
是LINQ中的扩展方法 - Count
是 List
,实际上是.NET集合对象的属性。
因此,由于它将枚举集合/可查询对象,所以 Count()
几乎总是更慢。 在列表、队列、栈等中使用 Count
。 或对于数组-使用 Length
。
Count
或Length
属性,你应该总是优先使用它们而不是Count()
方法,因为后者通常需要迭代整个集合来计算元素数量。例外情况是当Count()
方法针对LINQ to SQL或LINQ to Entities源时,它会执行一次针对数据源的计数查询。即使如此,如果存在Count
属性,你仍然应该优先使用它,因为它可能需要更少的工作量。Count()
方法对于 ICollection<T>
进行了优化,这将导致调用 Count
属性。在这种情况下,性能上可能没有显著的差异。
除了 ICollection<T>
之外,还有其他类型具有比 Count()
扩展方法更高效的替代方法。此代码分析性能规则适用于以下类型。
CA1829:使用 Length/Count 属性而不是 Enumerable.Count 方法。
System.Array
System.Collections.Immutable.ImmutableArray<T>
System.Collections.ICollection
System.Collections.Generic.ICollection<T>
System.Collections.Generic.IReadOnlyCollection<T>
Count
和Length
属性,否则回退到Count()
扩展方法。.Count
是集合的一个属性,用于获取集合中的元素。与 .Count()
不同,后者是 LINQ 的扩展方法,用于计算元素的数量。
通常情况下,.Count
比 .Count()
更快,因为它不需要创建和枚举 LINQ 查询的开销。
除非需要 .Count()
方法提供的额外功能(例如指定过滤谓词的能力),否则最好使用 .Count
属性。
int count = numbers.Count(n => n.Id == 100);
.
运算符。 - AaronLS