我何时应该在IEnumerable <t> </t>的上下文中使用.Count()和.Count

时间:2012-05-18 12:39:04

标签: c# .net linq generics collections

我知道.Count()是LINQ中的扩展方法,从根本上它使用.Count,所以我想知道,我应该何时使用Count()以及何时应该使用.Count我用.Count()?对于尚未执行的可查询集合,.Count()是否更好地保存,因此还没有枚举?我是否更安全?总是使用.Count()扩展方法,反之亦然?或者这是否完全取决于收藏?

非常感谢任何建议或文章。

更新1

在LINQ中反编译.Count扩展方法后,如果IEnumerable<T>ICollection<T>或{ICollection,则似乎正在使用.Count() 属性 {1}},这是大多数答案所建议的。现在我能看到的唯一真正的开销是额外的空值和类型检查,我认为这并不是很大,但如果性能至关重要,它仍然会产生一些差异。

这是.NET 4.0中反编译的LINQ public static int Count<TSource>(this IEnumerable<TSource> source) { 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; checked { using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { num++; } } return num; } } 扩展方法。

{{1}}

6 个答案:

答案 0 :(得分:10)

扩展方法适用于任何IEnumerable<T>,但它的成本很高,因为它通过迭代来计算序列。如果序列为ICollection<T>则意味着集合的长度已知,则会进行优化。然后使用Count属性,但这是一个实现细节。

最好的建议是出于性能原因使用Count属性。

  

对于尚未执行的可查询集合,.Count()是否更好地保存,因此还没有枚举?

如果您的收藏集是IQueryable<T>而不是IEnumerable<T>,那么查询提供商可能会以某种有效的方式返回计数。在这种情况下,您不会受到性能损失,但这取决于查询提供程序。

IQueryable<T>没有Count属性,因此在使用扩展方法和属性之间别无选择。但是,如果查询提供程序未提供有效的计算方法Count(),则可以考虑使用.ToList()将集合提取到客户端。这实际上取决于你打算如何使用它。

答案 1 :(得分:1)

当你拥有的是一个不公开Count或Length属性的接口时,你应该使用Count(),例如IEnumerabe<T>

如果您正在处理集合或集合界面(例如List<T>ICollection),那么您可以简单地使用Count属性,同样如果您有一个数组使用Length属性。< / p>

Count()扩展属性的实现将使用底层集合的Count属性(如果可用)。否则,将枚举该集合以计算计数。

答案 2 :(得分:1)

Count从List(已经计算)中检索属性。 Count()是一个聚合,如Sum(),Average()等。它的作用是计算枚举中的项(我相信如果枚举是列表,它在内部使用Count属性)。

这是一个具体使用Count()方法的例子,当它不只是使用Count属性时:

var list = new List {1,2,3,4,5,6,7,8,9,10};

var count = list.Where(x => x > 5).Count();

此外,Count()有一个重载,它将计算与谓词匹配的项:

var count = list.Count(x => x > 5);

答案 3 :(得分:1)

同意.Count的评论(如果可用)(即在发动机罩下实施ICollection<T>的对象)。

.Count()成本高昂是错误的。 Enumerable.Count()将在枚举元素并计算它们之前检查对象是否实现ICollection<T>.Count

即。像,

public int Enumerable.Count<TSource>(IEnumerable<TSource> source)
{
    var collection = source as ICollection
    if (collection != null)
    {
        return collection.Count;
    }
}

答案 4 :(得分:0)

我不确定这是否重要,因为Count()可能只是读取Count属性。性能差异确实可以忽略不计。使用您喜欢的任何一种。我尽可能使用Count()来保持一致。

答案 5 :(得分:0)

正如其他人所说,如果您有ICollection<T>,请使用Count属性。

我建议IEnumerable.Count()方法真的打算在你想要对枚举元素进行的唯一事件计算时使用。相当于SQL“SELECT COUNT(...”。

如果另外你想用枚举的元素做其他事情,那么生成一个集合(通常是使用ToList()的列表)更有意义,那么你可以使用Count属性并做任何其他事情你想做什么。

相关问题