9

我知道这.Count()是 LINQ 中的一种扩展方法,并且从根本上说它使用.Count,所以我想知道,我应该什么时候使用Count(),什么时候应该使用.Count?主要是.Count()为尚未执行的可查询集合更好地保存,因此还没有枚举?我总是使用扩展方法更安全.Count()吗,反之亦然?还是这完全取决于收藏?

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

更新 1

在 LINQ 中反编译扩展方法后,如果is an or ,.Count()它似乎正在使用该.Count 属性,这是大多数答案所建议的。现在我能看到的唯一真正的开销是额外的 null 和类型检查,我想这不是很大,但如果性能至关重要,仍然可以产生少量的差异。IEnumerable<T>ICollection<T>ICollection

这是.Count().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;
    }
}
4

6 回答 6

10

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

最好的建议是Count出于性能原因使用该属性(如果可用)。

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

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

AnIQueryable<T>将没有Count属性,因此在使用扩展方法和属性之间没有选择。但是,如果您的查询提供者没有提供一种有效的计算方式,Count()您可能会考虑使用.ToList()将集合拉到客户端。这实际上取决于您打算如何使用它。

于 2012-05-18T12:41:20.260 回答
1

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

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

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

于 2012-05-18T12:41:09.247 回答
1

Count 从列表中检索属性(已计算)。Count() 是一个聚合,如 Sum()、Average() 等。它的作用是对 enumerable 中的项目进行计数(如果 enumerable 是列表,我相信它在内部使用 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);
于 2012-05-18T12:46:03.580 回答
1

同意.Count它是否可用的评论(即ICollection<T>在引擎盖下实现的对象)。

But they are wrong about .Count() being 'costly'. Enumerable.Count() will check if the object implements ICollection<T>.Count before it enumerates the elements and count them.

I.e. something like,

public int Enumerable.Count<TSource>(IEnumerable<TSource> source)
{
    var collection = source as ICollection
    if (collection != null)
    {
        return collection.Count;
    }
}
于 2012-05-18T12:46:34.593 回答
0

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

于 2012-05-18T12:45:02.237 回答
0

As others have said, if you have an ICollection<T>, use the Count property.

I would suggest that the IEnumerable.Count() method is really intended for use when the only thing you want to do with the elements of an enumeration is count them. The equivalent of SQL "SELECT COUNT(...".

If in addition you want to do something else with the elements of an enumeration, it makes more sense to generate a collection (usually a list using ToList()), then you can use the Count property and do whatever else you want to do.

于 2012-05-18T13:07:57.140 回答