Count属性vs Count()方法?

75 c# linq collections list count

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

编辑:出于好奇,那么,如果集合为空,Count()会抛出异常吗?因为我很确定Count属性只返回0.

Ian*_*son 96

反编译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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • +1主动对此进行逆向工程,非常有帮助. (8认同)
  • 但是,请记住在3.5`Count()`中不检查非泛型的`ICollection`接口.这仅在.NET 4中添加.3.5和4都检查通用的`ICollection <T>`接口. (7认同)
  • 对没有元素的序列调用count会抛出异常.但Count()会正常工作. (2认同)

Aar*_*nLS 30

表现只是选择其中一个的一个原因.选择.Count()意味着您的代码将更通用.我曾经有过这样的场合,我重构了一些不再生成集合的代码,而是像IEnumerable那样更通用的东西,但其他代码因为它依赖.Count而破坏了我必须将其更改为.Count().如果我指出要.Count()在任何地方使用,代码可能更可重用和可维护.通常选择使用更通用的界面,如果你可以逃脱它是你最好的选择.通过更通用,我的意思是更简单的接口,由更多类型实现,从而为您提供更强的代码兼容性.

我不是说.Count()更好,我只是说有其他考虑因素更多地涉及你正在编写的代码的可重用性.

  • +1有价值的讨论增加.我维护的一些代码刚刚破解,因为属性.Count无法在HtmlAgilityPack的版本升级中存活. (2认同)
  • 这可能是一把双刃剑。如果有一天有人试图将 IEnumerable 修改为真正的生成器怎么办?查看代码库,我看到很多地方 .Count() 假设可枚举可以迭代多次 (2认同)

ang*_*son 18

.Count()方法可能足够智能,或者知道有问题的类型,如果是,它可能使用底层.Count属性.

然后,它可能不会.

我想可以安全地假设如果集合.Count本身具有属性,那么在性能方面这将是你最好的选择.

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

  • 使用 `Count` 属性可能会更好,但是使用 `ICollection&lt;T&gt;.Count` 制作的 `Count()` 方法在这里有点记录:https://msdn.microsoft.com/en-us/library/bb338038( v=vs.110).aspx (3认同)

Jar*_*Par 6

Count简短版本:如果您可以在属性和方法之间进行选择,Count()请始终选择属性。

差异主要在于操作效率。所有公开属性的 BCL 集合都Count以 O(1) 的方式进行。不过,该Count()方法可能而且通常会花费 O(N) 的成本。对于某些实现,有一些检查尝试使其达到 O(1),但这绝不是保证的。


Dyl*_*ith 5

Count()方法是适用于任何IEnumerable<>. 您可能期望该Count()方法迭代整个集合来查找计数,但我相信 LINQ 代码实际上有一些优化来检测 Count 属性是否存在,如果存在则使用它。

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


Ant*_*ioR 5

Count()方法是一个扩展方法,它迭代IEnumerable <>的每个元素并返回有多少元素.如果IEnumerable的实例实际上是List <>,那么它被优化以返回Count属性而不是迭代所有元素.