【发布时间】:2013-01-29 17:02:23
【问题描述】:
我知道在 .net 集合类型(或至少某些集合类型)中,当您对其进行迭代时,不允许修改集合。
例如在 List 类中存在这样的代码:
if (this.version != this.list._version)
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
但显然这是设计迭代器类的开发人员的决定,因为我可以提供IEnumerable 的一些实现,至少在底层集合被修改时不会抛出任何异常。
那我有几个问题:
为什么在迭代集合时不应该修改它?
是否可以创建一个支持在对其进行迭代时进行修改的集合,而不会出现任何其他问题? (注意:第一个答案也可以回答这个)
当C#编译器生成
Enumerator接口实现时会考虑到这种情况吗?
【问题讨论】:
-
ConcurrentDictionary 允许在枚举时进行修改。
-
@ken2k
ConcurrentDictionary以及该命名空间中的其他集合,不返回迭代集合的迭代器。他们将所有元素复制到一个临时命名空间并返回该集合的迭代器,这提供了一个永远不会修改的集合的迭代器。当您期望底层数据在迭代期间发生变化时,这是为序列提供迭代器的一种方法。 -
@Servy:
ConcurrentDictionary的文档明确指出,不能保证它返回的项目组合代表实际存在的状态的快照。例如,如果一个线程按顺序添加“Moe”和“Curly”,而另一个线程正在尝试枚举字典,则不能保证第二个线程在没有看到“Moe”的情况下看不到“Curly”。我相信枚举过程中未添加或删除的项目保证返回一次,枚举过程中添加或删除的项目最多返回一次。
标签: c# .net collections ienumerable