【问题标题】:Why is Dictionary.Add overwriting all items in my dictionary?为什么 Dictionary.Add 会覆盖我字典中的所有项目?
【发布时间】:2012-04-23 17:02:23
【问题描述】:

我有一个Dictionary<string, IEnumerable<string>> 类型的字典和一个字符串值列表。出于某种原因,每次我执行 Add 时,字典中的每个值都会被覆盖。我完全不知道为什么会这样。我确保在循环中声明和初始化 IEnumberable 对象不是参考问题,这样它的范围就不会超出一次迭代,它仍然会这样做。这是我的代码:

foreach (string type in typelist)
{
    IEnumerable<string> lst = 
        from row in root.Descendants()
        where row.Attribute("serial").Value.Substring(0, 3).Equals(type)
        select row.Attribute("serial").Value.Substring(3).ToLower();

    serialLists.Add(type, lst);
}

其中typelistIEnumerable&lt;string&gt;rootXElementserialLists 是我的字典。

【问题讨论】:

  • 你已经“关闭了循环变量”。您添加的每个 lst 都将使用 last type 变量。请阅读:blogs.msdn.com/b/ericlippert/archive/2009/11/12/… 有趣的是,这个问题将在 C#5 中消失!
  • 我一定会阅读的。再次感谢大家的帮助!

标签: c# linq dictionary


【解决方案1】:

这是一个捕获的迭代器问题。

试试:

foreach (string tmp in typelist)
{
   string type = tmp;

(其余不变)

或者,我会在添加过程中评估表达式,即在 .Add 中执行 .ToList():

    serialLists.Add(type, lst.ToList());

第二个选项总体上可能更有效,尽管它确实强制评估可能永远不需要的东西。

【讨论】:

  • 谢谢!这立即解决了问题。
【解决方案2】:

原因是您的IEnumerable&lt;string&gt; 序列没有被急切地填充,而是按需填充,之后foreach 循环将完成其所有迭代。因此,当枚举任何IEnumerable&lt;string&gt; 序列时,type 变量将始终具有typelist 中最后一个元素的值。

这是一种简单的修复方法:

foreach (string type in typelist)
{
    string typeCaptured = type;

    IEnumerable<string> lst = 
        from row in root.Descendants()
        where row.Attribute("serial").Value.Substring(0, 3).Equals(typeCaptured)
        select row.Attribute("serial").Value.Substring(3).ToLower();

    serialLists.Add(typeCaptured, lst);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 2015-01-27
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    相关资源
    最近更新 更多