OrderedDictionary打破了.NET 4的变化?

时间:2011-03-01 19:24:38

标签: .net .net-4.0

我们正在努力将项目升级到.NET 4时,我的一位同事遇到了这个。

给出以下代码:

 var od = new System.Collections.Specialized.OrderedDictionary();

 od.Add("key1", "value1");
 od.Add("key2", "value2");

 foreach (System.Collections.DictionaryEntry entry in od)
 {
     od[entry.Key] = null;
 }

在.NET 3.5中,将条目设置为null将正常工作。正如预期的那样,密钥仍然在字典中,其匹配值将为null。

在.NET 4.0中,这会抛出一个InvalidOperationException,表示

  

收藏被修改;枚举操作可能无法执行。

我想也许OrderedDictionary有一个更改,其中将一个条目设置为null将完全删除它,但是进行快速测试表明当你将它设置为null时,该条目仍然存在。

这是一个未经报道的突然变化吗?

4 个答案:

答案 0 :(得分:7)

来自 System.Collections.Specialized.OrderedDictionary Class

  

foreach语句是枚举器的包装器,它只允许读取而不是写入集合。

我认为这意味着你错误地使用它,并且你以这种方式使用它是你的错。它不应该起作用,现在也不起作用。

答案 1 :(得分:7)

你发现了一个突破性的变化。在先前版本的OrderedDictionary中,内部OrderedDictionaryEnumerator类使用数组索引来遍历数组。只要项目未被删除添加,就不会抱怨。

新版本使用数组本身通过GetEnumerator返回的基础枚举器,这就是您看到代码失败的原因。

话虽如此,但这只是一个突然改变应该永远不会以开始。以任何方式修改您要枚举的集合,无论是通过foreach循环还是明确使用IEnumerator,都是完全违法的。您找到的是一个已修复的错误。

答案 2 :(得分:4)

这是一个错误修复。反馈文章触发了修复is here

答案 3 :(得分:1)

该错误与null无关。它与您在foreach循环中修改集合的事实有关。这样做会使迭代器无效并中断枚举过程。

您可以安全地将值设置为null(对于可为空的值类型,即),在foreach的外部

即,这将起作用:

od.Add("key2", null);