是否保证ArrayList的版本号不会溢出
本文关键字:溢出 版本号 ArrayList 是否 | 更新日期: 2023-09-27 18:00:19
我正在研究.NET 4.5.1 ArrayList
类的实现,我注意到它在内部存储了一个版本号,以跟踪对列表所做的更改。一些观察者类(如ArrayList
的枚举器)使用此版本号来检查在该只读操作期间是否修改了列表。
这个版本号是一个int
,只是一个计数器:每个可变操作都会增加版本号。因此,我们能够在ArrayList
上执行有限数量的可变操作,直到版本号溢出为止。
在C#中,整数溢出默认不会引发异常,因此ArrayList
的版本号可能会发生溢出,而不会立即引发异常。我的问题是:是否保证ArrayList
的版本号不会溢出,或者如果溢出,基于版本号的检查过程不会失败
我想到的是一个应用程序对大型元素集执行操作,这些操作会溢出ArrayList
的版本号,从而导致ArrayList
版本控制错误。
不,不能保证。但你不应该担心。你真的不可能因为这种行为而痛苦。
然而,您可以想象这样的情况,例如,当您获得一个枚举器时,使用GetEnumerator
方法,开始枚举集合,同时更改适当的次数以使version
计数器溢出并再次返回到相同的值。如果Collection changed消息,则进一步的枚举应该会失败,但不会,因为version
编号与以前完全相同。
顺便说一句,同样的事情也适用于例如List<T>
。
当它溢出时(例如,如果在一年中每天操作>68次),它将变为-2147483648。对它的唯一检查是与上一个已知版本是否相等,而不是"大于/小于"(afaik),这样你就不会出现任何错误。
因此,你只担心它会溢出,并在两次检查之间再次变成相同的数字。虽然可能,但极不可能:
- 每秒添加6000万次,仍然需要>10分钟才能达到相同的数字,然后您需要在那之前进行检查,才能"看不到"最后43亿次版本更改†。你不太可能看到这种情况发生
- 您还需要在数字递归的同时进行检查,这也是极不可能的⏴
- 如果你真的看到了,那就买一张彩票,这一定是你的幸运周
稍后编辑:不过,我想这里最重要的一点是,你不应该真的能够做到这一点。如果您在同时(同步或并行)添加和删除时枚举,则使用了错误的方法:使用BlockingCollection
、事件、反应型编程之类的方法,或者仅锁定ArrayList
进行多线程访问。因此,这是一个很好的理论问题,你永远不应该担心它
†如果你每秒添加6000万个项目,并花10分钟在整个数组列表中枚举一个项目,从而发现版本更改,那么你还有其他事情要担心。
4294967296中的⏹1,精确地说是