确定对icollectioncount的调用是否会导致迭代

本文关键字:迭代 是否 调用 icollectioncount | 更新日期: 2023-09-27 17:54:39

假设我想从Collection访问一个对象,并且我想确定它不会遍历整个Collection来确定大小。

我如何确定和控制如果调用Count导致实际迭代通过集合?(除了使用我自己的ICollection实现),换句话说,有实现提供这一点吗?

public void PrintThreeNames(ICollection<string> names)
{
    //first I want to know if the collection has at least three elements.
    if (names != null && names.Count >= 3)
    {
        IEnumerator<string> enumerator = names.GetEnumerator();
        string value0 = enumerator.Current;
        enumerator.MoveNext();
        string value1 = enumerator.Current;
        enumerator.MoveNext();
        string value2 = enumerator.Current;
        //print values.
        Console.Writeline(value0 + value1 + value2);
    }
}

回应程序员英雄问题。我想我可以让一个IEnumerable<T>集合向它添加一百万个文档,并计算一下对Count的调用有多快。

我问这个问题是因为我可能会选择使用IEnumerable而不是Collection,因为我的集合在数量和每个项目的数据上都是如此之大,因此一次返回所有它们将是一个问题。

然而,我也想知道IEnumarable的缺点,Joshua在另一个问题中指出锁定它不是一个好主意。

确定对icollectioncount的调用是否会导致迭代

是否存在相对昂贵的Count实现?有可能,但它们很少见;. net框架类被调优为非常好的全面效率。

重要吗?几乎可以肯定不会。除非您在包含数百万个元素的集合上查询Count数百万次,否则差异非常小,以至于无关紧要:

  • 1亿个呼叫List<T>.Count,包含100万个整数:0.85s
  • 1亿个呼叫HashSet<T>.Count(),包含100万个整数:1.45秒

因为ICollection将Count暴露为一个属性,所以可以安全地假设获取它的值是非常便宜的(即它不应该遍历整个集合)。

这只是一个关于属性的最佳实践-获取它们的值应该是便宜的-周期。

如果操作是昂贵的,那么它应该是一个方法-例如Count()。

当然,有人可以提供一个昂贵的iccollection实现。计数-然而,那个人没有做正确的事情。

如果计算元素的数量是昂贵的,它们应该只实现IEnumerable而不是ICollection。

从技术上讲,因为ICollection是一个接口,所以不能保证它不会遍历集合。该接口无论如何都可以实现。