.NET4中的OrderedDictionary破坏性更改?
前几天,我的一位同事在将一个项目升级到.NET4时遇到了这个问题 给定以下代码:.NET4中的OrderedDictionary破坏性更改?,.net,.net-4.0,.net,.net 4.0,前几天,我的一位同事在将一个项目升级到.NET4时遇到了这个问题 给定以下代码: 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;
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;
}
在.NET3.5中,将条目设置为null可以正常工作。正如预期的那样,密钥仍然在字典中,其匹配值将为null
在.NET4.0中,这抛出了一个InvalidOperationException,表示
收集被修改;枚举操作不能执行
我认为OrderedDictionary可能有一个更改,将条目设置为null将完全删除它,但是快速测试表明,当您将条目设置为null时,条目仍然存在
这是一个未报告的突破性变化吗?来自:
foreach
语句是围绕枚举数的包装器,它只允许读取集合,不允许写入集合
我相信这意味着你没有正确地使用它,你以这种方式使用它是你的错。它本不应该工作,现在也不工作。该错误与null无关。这一切都与您在
foreach
循环中修改集合有关。这样做会使迭代器无效并中断枚举过程
您可以在foreach之外安全地将值设置为null(对于可为null的值类型)
也就是说,这将起作用:
od.Add("key2", null);
你发现了一个突破性的变化。在以前版本的
OrderedDictionary
中,内部OrderedDictionaryEnumerator
类使用数组索引来遍历数组。只要项目没有被删除或添加,它就不会抱怨
新版本使用了数组本身通过GetEnumerator
返回的基础枚举数,这就是代码失败的原因
话虽如此,这只是一个突破性的改变,一开始就不应该奏效。无论是通过
foreach
循环还是显式使用IEnumerator
,以任何方式修改要枚举的集合都是完全非法的。您发现的是一个已修复的bug。这是一个bug修复。触发修复的反馈文章。你确定问题不在于试图在foreach
循环中更改条目,而不是简单地将其设置为null
?也就是说,它是在.NET 4.0中修复的(我必须阅读文章三次才能理解它:-)链接断开了-它重定向到一个通用页面,“Microsoft Connect已退役”。对此我无能为力。在过去8年中没有任何变化,它仍然是由一份错误报告引发的.NET 4.0中的一个错误修复。值得注意的是,.NET 4.0摸索了一个类似的签入,在4.5中再次修复,但现在更迫切地需要向后兼容。谢谢(以及所有其他回答的人)。我不敢相信我在文档中忽略了这一点!尽管枚举是以文档的方式记录的,但有一个长期的传统,即允许枚举器在修改源集合时保持功能,只要其行为合理。类似于ConcurrentDictionary
上的枚举器将非常有用没有这样的能力。