Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET4中的OrderedDictionary破坏性更改?_.net_.net 4.0 - Fatal编程技术网

.NET4中的OrderedDictionary破坏性更改?

.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;

前几天,我的一位同事在将一个项目升级到.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;
 }
在.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
上的枚举器将非常有用没有这样的能力。