ArrayList计数与任意

本文关键字:任意 ArrayList | 更新日期: 2023-09-27 18:01:03

我正在研究一些遗留代码。该类使用ArrayList来保留项。这些项目是从数据库表中提取的,最多可达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作为IEnumerable

哪种方法性能更好:.Any((与.Count((>0?

ArrayList计数与任意

.NET引用源表示ArrayList.Count返回一个缓存的私有变量。

为了完整起见,源代码还在这里列出了Any((扩展方法的实现。本质上,扩展方法执行null检查,然后尝试通过IEnumerable的枚举器获取第一个元素。

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;
Marc Gravel建议使用Any()而不是Count()(扩展方法(,但不一定要使用Count(属性(。

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

现在,这一切对于性能来说都是微不足道的,但执行这项操作的代码更为复杂,因此只有在具有显著性能优势的情况下才应该使用它。由于实际上存在微不足道的性能损失,我们应该选择更简单的代码。因此,我将把Any()实现为return Count > 0;

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

ArrayList实现IList,因此它确实具有Count属性。如果您只关心检查容器(非(空,那么使用它将比Any()更快。