2010-08-08 76 views
5

我可以安全地將節點添加到LinkedList容器內的foreach語句中嗎?如果我使用while循環,有什麼區別嗎?或者它從來不被允許,並可能導致一些問題?添加節點到LinkedList <T>在foreach

foreach(var node in myList) 
{ 
    if(condition) 
     myList.AddLast(new MyNode()); 
} 

請問它總是工作?

回答

6

在枚舉時不能修改集合。

docs for LinkedList<T>.GetEnumerator

一個枚舉仍然有效的,只要 集合保持不變。如果 對集合進行了更改,如 (如添加,修改或刪除元素),則枚舉數爲 將無法​​恢復,並且其 行爲未定義。

在實踐中,我相信它總是會拋出一個InvalidOperationException,儘管這種行爲尚未定義。

編輯:你問的評論的while循環是否會幫助...使用while循環GetEnumerator/MoveNext/Current不會,但這會:

LinkedListNode<MyNode> current = myList.First; 
while (current != null) 
{ 
    if (condition) // use current.Value to get the value 
    { 
     myList.AddLast(new MyNode()); 
    } 
    current = current.Next; 
} 

至於我意識到,這是完全安全和可預測的。您始終可以要求節點爲其下一個節點。如果您恰好在查看尾節點並添加另一個節點,則當您要求「下一個」時,您將獲得新的尾節點。

如果這沒有幫助,請給我們更多關於你想要實現的細節。

+0

如果新節點符合條件,則完全安全的是一個伸展,無限循環和OOM。 – 2010-08-08 19:45:32

1

在使用foreach語句迭代集合時,無法對其進行修改。因此,添加項目會導致編譯器錯誤。

+0

會用'while'循環解決我的問題嗎? – 2010-08-08 19:27:32

+1

您可以使用'while'循環來循環收集。這樣做時不會收到編譯器錯誤,但要小心不要寫入無限循環 - 如果新的MyNode()實現了'condition',則會發生這種情況。 – 2010-08-08 19:31:26

+3

它*不會導致編譯器錯誤。給出的代碼將毫無問題地編譯。它會在執行時拋出異常。 – 2010-08-08 19:32:40

2

不,枚舉器對象會記住擁有集合的內部版本。收集後修改 - 版本更改,所以foreach將失敗。

+0

+1用於查看反射器以查看統計員如何執行檢查:) – Ani 2010-08-08 19:40:49

0

也許你可以將它們添加到新列表。然後在最後,在foreach之外使用.addrange()將新的附加到原始列表。