[c#]为什么同样的 LINQ 表达式在两个不同的 foreach 循环中表现不同吗?

标签: C#
发布时间: 2013/12/3 6:28:08
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

以下 XML 了

<Parts>
  <Part name="Part1" disabled="true"></Part>
  <Part name="Part2" disabled="false"></Part>
  <Part name="Part3" ></Part>
  <Part name="Part4" disabled="true"></Part>  
</Parts>

我想要移除的节点的 disabled 属性设置为 true 。如果 '残疾' 属性不用于任何 '部分' 元素,这意味着它未被禁用。

我写了以下代码:

XmlNode root = xmlDoc.DocumentElement;
List<XmlNode> disabledNodes = new List<XmlNode>();
foreach(XmlNode node in root.ChildNodes)
{
    if(node.Attributes["disabled"] != null && 
        Convert.ToBoolean(node.Attributes["disabled"].Value))
    {
        disabledNodes.Add(node);
    }
}

foreach (XmlNode node in disabledNodes)
{
    root .RemoveChild(node);
}

此代码将 2 个节点删除从 XML 像预期的那样。

我后来写了以下代码,以使代码更紧凑:

foreach (XmlNode node in root.ChildNodes.Cast<XmlNode>()
    .Where(child => child.Attributes["disabled"] != null && 
    Convert.ToBoolean(child.Attributes["disabled"].Value)))
{
    root.RemoveChild(node); // This line works fine without any exception.
}

我发现了这种循环循环只有一次,从 XML 中删除只有一个节点。


已编辑的问题:

现在,当我更改 foreach 循环,这一次我将转换到 LINQ 表达式的结果 List<T> 使用 ToList() 方法 (作为 @Toni 彼得林娜在他的回答中的建议)。而这一次它可以正常工作 !

 foreach (XmlNode node in root.ChildNodes.Cast<XmlNode>()
        .Where(child => child.Attributes["disabled"] != null && 
        Convert.ToBoolean(child.Attributes["disabled"].Value)).ToList())
    {
        root.RemoveChild(node); // This line works fine without any exception.
    }

为什么使用 ToList() 所作工作的 LINQ 表达式 foreach 循环像预期的那样吗?为什么 LINQ 的结果行为的不同两种不同情况下任何技术原因吗?

我使用的.NET 4.0。

解决方法 1:

编写:

foreach (XmlNode node in root.ChildNodes.Cast<XmlNode>()
    .Where(child => child.Attributes["disabled"] != null && 
    Convert.ToBoolean(child.Attributes["disabled"].Value)).ToList())
{
    root.RemoveChild(node);
}

我已经添加额外 tolist () 强制立即执行的 LINQ 表达式。

当您创建 LINQ 查询时,你得到 IEnumerable 集合,实际上并不持有任何结果。即使你写的所有这些选择和凡和许多其他子句,完整的查询不是执行之前先对它进行迭代。然后只运行实际查询。

在原始的代码中,您创建一个查询并开始对它进行迭代。您收到的第一项通过 LINQ 的所有子句和删除的第一个节点。但因为你遍历根集合,现在修改,迭代停止。

您不能更改的 foreach 循环体内循环访问该集合。

官方微信
官方QQ群
31647020