关于c#:Count属性vs Count()方法?

Count property vs Count() method?

使用集合,我有两种获取对象计数的方法:count(属性)和count()方法。有人知道什么是关键区别吗?我可能是错的,但我总是在任何条件语句中使用Count属性,因为我假设Count()方法对集合执行某种查询,其中As Count必须在我"获取"之前就已被分配。但这只是猜测-如果我错了,我不知道性能是否会受到影响。

编辑:出于好奇,那么,如果集合为空,count()是否会引发异常?因为我很确定Count属性只返回0。


Count()扩展方法的源代码进行反编译,可以测试对象是否是ICollection(泛型或其他)对象,如果是这样,只返回基础Count属性:

因此,如果您的代码访问Count,而不是调用Count(),那么您可以绕过类型检查——这是一个理论上的性能优势,但我怀疑它是否值得注意!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 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()意味着您的代码将更通用。我曾经重构过一些不再生成集合的代码,而是一些更通用的代码,比如IEnumerable,但是由于依赖于.Count,所以其他代码中断了,我不得不将其更改为.Count()。如果我指出在任何地方都使用.Count(),代码可能更易于重用和维护。通常选择使用更通用的接口,如果你能摆脱它是你最好的选择。我所说的更通用,是指由更多类型实现的更简单的接口,从而使代码之间的兼容性更强。

我不是说.Count()更好,我只是说还有其他一些考虑因素可以更好地处理您正在编写的代码的可重用性。


.Count()方法可能足够聪明,或者知道所讨论的类型,如果是这样,它可能使用基础.Count属性。

再说一遍,可能不会。

我想说,如果集合本身有一个.Count属性,那么在性能方面这将是您最好的选择。

如果.Count()方法不知道集合,它将枚举它,这将是一个O(N)操作。


count()方法是一个扩展方法,它迭代IEnumerable<>的每个元素,并返回有多少个元素。如果ienumerable的实例实际上是一个列表<>,那么最好返回count属性,而不是迭代所有元素。


如果存在count或length属性,则应始终首选count()方法,该方法通常迭代整个集合以计算其中的元素数。(例外情况是,当count()方法针对linq to sql或linq to entities源时,例如,在这种情况下,它将对数据源执行count查询。即使这样,如果有Count属性,您也希望这样做,因为它可能要做的工作更少。)


短版本:如果在Count属性和Count()方法之间进行选择,则始终选择该属性。

差别主要在于操作的效率。公开Count属性的所有bcl集合都以o(1)的方式这样做。虽然Count()方法可以而且通常会花费O(n)。对于某些实现,有一些检查尝试将其传递给O(1),但这并不能保证。


count()方法是在任何IEnumerable<>上工作的Linq方法。您会期望count()方法在整个集合中迭代以查找count,但我相信linq代码实际上在其中有一些优化,以检测是否存在count属性,如果存在,则使用该属性。

所以他们都应该做几乎相同的事情。Count属性可能稍微好一点,因为不需要在其中进行类型检查。


Count()是linq-Count的一个扩展方法,它是List的一个属性,实际的.NET集合对象。

因此,Count()几乎总是较慢,因为它将枚举集合/可查询对象。在列表、队列、堆栈等中,使用Count。或者对于数组-Length