2016-06-10 48 views
0

我很惊讶地看到,并非所有我在下面的代码元素被迭代:迭代的IEnumerable与linq2xml

IEnumerable<XElement> dataStorageGroupElements = document.Descendants().Where(x => "Xms.Common.DataStorageGroup" == (string)x.Attribute("NodeType")); 
int counter = 0; 
foreach (XElement dataStorageGroupElement in dataStorageGroupElements) 
{ 
    Console.WriteLine($"Counter={counter++}, NbElements={dataStorageGroupElements.Count()}"); 
    XElement newParent = GetNewParentForDataStorageGroup(dataStorageGroupElement); 
    dataStorageGroupElement.Remove(); 
    newParent.Add(dataStorageGroupElement); 
} 

输出是:

Counter=0, NbElements=12 
Counter=1, NbElements=12 
Counter=2, NbElements=12 
Counter=3, NbElements=12 
Counter=4, NbElements=12 
Counter=5, NbElements=12 
Counter=6, NbElements=12 

更改代码来执行枚举与ToArray()修复此问题:

IEnumerable<XElement> dataStorageGroupElements = document.Descendants().Where(x => "Xms.Common.DataStorageGroup" == (string)x.Attribute("NodeType")).ToArray(); 

用上面的代码计数器正在增加ent to 11.

为什么有些元素被跳过描述为here。但为什么NbElements总是12?是否仅在第一次评估?

+0

您的意思是linq to xml? – Cosmin

+0

@Cosmin是的,我确实:/修正了 – Philippe

回答

3

的问题在MSDN描述:"Mixed declarative code/imperative code bugs (LINQ to XML)"

的LINQ to XML包含各种方法,使您可以直接修改XML树。您可以添加元素,删除元素,更改元素的内容,添加属性等。此编程接口在修改XML树(LINQ to XML)(C#)中进行了介绍。如果您要遍历其中一个轴(如Elements),并且您在遍历轴时修改XML树,则最终会出现一些奇怪的错误。

这个问题有时被称为“万圣节问题”。

基本上,当你懒洋洋地迭代它时修改某些东西是一个坏主意。在开始修改内容之前使用ToArray来实现查询的方法是正确的,尽管我个人使用ToList而不是ToArray