是否保证ArrayList的版本号不会溢出?

时间:2014-04-27 13:50:14

标签: c# arraylist

我正在查看.NET 4.5.1 ArrayList类的the implementation,我注意到它在内部存储了一个版本号,用于跟踪对列表所做的更改。某些观察者类(如ArrayList的枚举器)使用此版本号来检查列表是否在该只读操作期间被修改。

该版本号是int,只是一个计数器:每个可变操作都会增加版本号。因此,我们能够在ArrayList上执行有限数量的可变操作,直到版本号溢出。

默认情况下,整数溢出不会在C#中抛出异常,因此ArrayList的版本号可能会发生溢出,而不会立即抛出异常。我的问题是:是否保证ArrayList的版本号不会溢出,或者如果它确实溢出,基于版本号的检查过程不会失败?

我想到的是一个应用程序对大量元素进行操作会导致ArrayList s版本号溢出导致ArrayList版本错误。

2 个答案:

答案 0 :(得分:4)

不,它不能保证。但你不应该担心这一点。你很可能不会遭受这种行为。

然而,你可以想象一下情况,例如你得到一个枚举器,使用GetEnumerator方法,开始枚举集合,同时改变它适当的次数使version计数器溢出并再次返回相同的值。进一步枚举应该会因 Collection changed 消息而失败,但它不会因为version号与之前完全相同而无法使用。

顺便说一下,同样适用于到List<T>

答案 1 :(得分:2)

当它溢出时(例如,如果你每天以每秒68次操作,一年一次),它将变为-2,147,483,648。对它的唯一检查是与上一个已知版本相等,而不是“大于/小于”(afaik),所以你不会得到任何错误。

因此,您只担心它会溢出,并且在检查之间再次成为相同的数字。虽然可能,但这是极不可能的:

  1. 每秒增加6000万,仍然需要&gt; 10分钟达到相同的数字,然后你需要没有做检查,直到“看不到”最后43亿版本的变化。你不太可能看到这种情况发生。
  2. 您还需要在数字重现的同时进行检查,这也是非常不可能的
  3. 如果你确实看到了,那就买彩票,这一定是你的幸运周。
  4. 稍后编辑:我想这里最重要的一点是,你不应该真的能够做到这一点。如果您同时(同步或并行)枚举添加和删除,则使用错误的方法:使用BlockingCollection,事件,反应类型编程之类的东西,或者只需将ArrayList锁定为多个线程访问。因此,这是一个很好的理论问题,你永远不必担心它。

    如果您每秒添加6000万个项目,并且需要花费10分钟来枚举整个arraylist中的单个项目,从而发现版本更改,您还需要担心其他事项。 / p> 确切地说,

    1 in 4,294,967,296