考虑以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(@"<Parts>
<Part name=""DisappearsOk"" disabled=""true""></Part>
<Part name=""KeepMe"" disabled=""false""></Part>
<Part name=""KeepMe2"" ></Part>
<Part name=""ShouldBeGone"" disabled=""true""></Part>
</Parts>");
XmlNode root = xmlDoc.DocumentElement;
List<XmlNode> disabledNodes = new List<XmlNode>();
try
{
foreach (XmlNode node in root.ChildNodes.Cast<XmlNode>()
.Where(child => child.Attributes["disabled"] != null &&
Convert.ToBoolean(child.Attributes["disabled"].Value)))
{
Console.WriteLine("Removing:");
Console.WriteLine(XDocument.Parse(node.OuterXml).ToString());
root.RemoveChild(node);
}
}
catch (Exception Ex)
{
Console.WriteLine("Exception, as expected");
}
Console.WriteLine();
Console.WriteLine(XDocument.Parse(root.OuterXml).ToString());
Console.ReadKey();
}
}
}
当我在Visual Studio Express 2010中运行此代码时,正如预期的那样,我没有遇到异常。我期待一个,因为我在迭代列表时从列表中删除了一些东西。
我得到的是一个列表,只删除了第一个子节点:
为什么我没有收到无效操作异常?
请注意,IDEOne.com 中的等效代码确实给出了预期的异常:http: //ideone.com/qoRBbb
另请注意,如果我删除所有 LINQ ( .Cast().Where()
),我会得到相同的结果,只删除一个节点,没有例外。
我在 VSExpress 中的设置有问题吗?
请注意,我知道涉及延迟执行,但我希望 where 子句在迭代源枚举(子注释)时迭代,这将给出我期望的异常。
我的问题是我在 VSexpress 中没有得到那个异常,但在 IDEOne 中得到了(我希望在两种/所有情况下都会出现这种情况,或者至少如果没有,我希望得到正确的结果)。
从Wouter 的回答看来,当第一个孩子被删除时,它似乎使迭代器无效,而不是给出异常。有没有官方这么说的?在其他情况下是否会出现这种行为?我会调用以静默方式使迭代器无效,而不是使用“静默但致命”异常。