我们正在努力将项目升级到.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时,该条目仍然存在。
这是一个未经报道的突然变化吗?
答案 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);