枚举.NET集合时,MSDN states表示:
只要集合保持不变,枚举器仍然有效。如果对集合进行了更改,例如添加,修改或删除元素,则枚举数将无法恢复,并且其行为未定义。
“无法恢复的无效”究竟是什么意思?
例如,使用二叉树,引用既可以向下也可以是向左和向右的子项,也可以是父对象。在这样的树中,对树中单个节点的单个引用足以在树中导航,因为您可以从中轻松找到树中的下一个节点。
所以使用那棵树,假设我删除了一些其他节点(可能是我没有删除我当前所在的节点),我是否仍然使枚举器无效?请注意,我不是在谈论多线程操作,只是运行循环的单个线程,以及修改循环体内的集合。
这个“法律”真的是一个法律吗,即使调查员可以继续,它也不应该?
答案 0 :(得分:8)
这个“法律”真的是法律吗,即使调查员可以继续,也不应该这样吗?
就我个人而言,我认为让你的普查员投掷,即使理论上可以继续,也是一种很好的做法。
通常,人们无意中将更改集合的代码放在foreach循环中。如果不这样做,它可能不会抛出开发人员当前正在测试的特定实例,但是不同的运行时条件可能很容易使它抛出。
总是抛出,你强迫开发人员将代码与框架的集合和枚举一样对待,我认为这是件好事,因为它可以降低处理库时的惊喜程度。
答案 1 :(得分:2)
标准馆藏统计员的实施使其成为一项法律。创建它们时,它会从集合对象中复制一个私有的“版本”整数。修改集合会增加该版本。迭代器方法比较版本,当它抛出不匹配时。没办法解决这个问题。
但是,有一个集合类允许在枚举时修改集合:Microsoft.VisualBasic.Collection。它需要这样做以保持与VB6 Collection类兼容。你可能想看看它是如何完成的。 IIRC,它在所有迭代器上保留WeakReference,然后在修改集合时更新迭代器。当然,这不是万无一失的,删除元素并将其重新添加可以枚举相同的对象两次。也不便宜。