2016-06-10 31 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