ArrayList计数与任何

时间:2014-04-29 22:10:41

标签: c# arraylist any

我正在查看一些遗留代码。该类使用ArrayList来保留项目。这些项目从Database表中获取,最多可达600万。该类公开了一个名为“ListCount”的方法来获取Arraylist中项目的计数。

Class Settings
{
    ArrayList settingsList ;
    public Settings()
    {
      settingsList = GetSettings();//Get the settings from the DB. Can also return null
    }

    public int ListCount
    {
        get
        {
           if (settingsList == null )
             return 0;
           else
             return settingsList.Count;
        }
    }
}

ListCount用于检查列表中是否有项目。我想知道在课堂上引入'Any'方法。

public bool Any(Func<vpSettings, bool> predicate)
{
   return settingsList !=null && settingsList.Cast<vpSettings>().Any(predicate);
}

问题是框架是否进行某种优化并维护项目的计数,还是在Arraylist上进行迭代以获得计数?如上所述添加“Any”方法是否可取。

Marc Gravel在下面的问题中建议使用Any for IEnumerable

  

Which method performs better: .Any() vs .Count() > 0?

4 个答案:

答案 0 :(得分:4)

.NET reference source表示ArrayList.Count返回一个缓存的私有变量。

为了完整性,the source还列出了Any()扩展方法的实现。本质上,扩展方法执行空检查,然后尝试通过IEnumerable的枚举器获取第一个元素。

答案 1 :(得分:2)

ArrayList实际上正在实施IList,它应该比.Any()更快。这是因为它实现了Count Property而不是Count MethodCount Property应该快速检查然后抓住适当的财产。

看起来类似于:

ICollection<TSource> collection1 = source as ICollection<TSource>;

  if (collection1 != null)
    return collection1.Count;

  ICollection collection2 = source as ICollection;

  if (collection2 != null)
    return collection2.Count;

答案 2 :(得分:2)

Marc Gravel建议使用Any()而非Count()(扩展方法),但不一定超过Count(属性)。

Count属性总是会更快,因为它只是查找存储在堆上的int。使用linq需要(相对)昂贵的对象分配来创建IEnumerator,加上MoveNext中的任何开销(如果列表不为空,将不必要地将ArrayList的第一个成员的值复制到Current属性)在返回真实之前)。

现在这对于性能来说非常简单,但是执行它的代码更复杂,所以只有在具有引人注目的性能优势时才应该使用它。由于这实际上是一个微不足道的性能损失,我们应该选择更简单的代码。因此,我会将Any()实施为return Count > 0;

但是,您的示例是实现Any的参数化重载。在这种情况下,您的解决方案,委托参数化Any扩展方法似乎是最好的。参数化的Any扩展方法和Count属性之间没有任何关系。

答案 3 :(得分:1)

ArrayList实现IList,因此它具有Count属性。使用它会比Any()更快,如果你关心的是检查容器(非)空虚。