2009-09-15 52 views
1

情況是這樣的:的foreach而將項目添加到收藏循環

我翻閱了一些代碼,我想知道,如果下面的語句需要選擇的集合或副本的參考與它取代了原來的foreach循環結束時的對象。如果第一個,它會把新找到的頁面加入循環中嗎?

foreach(Page page in Pages) 
{ 
    page.AddRange(RetrieveSubPages(page.Id)); 
} 

編輯:對不起,我犯了一個錯字。

它應該是這樣的:

foreach(Page page in pages) 
{ 
    pages.AddRange(RetrieveSubPages(page.Id)); 
} 

什麼,我想說的是,如果我的一些對象添加到收藏枚舉,將其加入在foreach這些對象?

回答

1

在回答你的問題,它不會使一個副本。

它創建通過集合的枚舉和迭代。如果在此枚舉正在發生集合更改,在foreach本身,或異步,你會得到一個異常:

「System.InvalidOperationException」類型的未處理的異常出現在mscorlib.dll

更多信息:收集已修改;枚舉操作可能不會執行。

您可以使用一個臨時集合並在之後加入兩個或者不使用枚舉器。

for (int i = 0; i < pages.Count; i++) 
    { 
     test.AddRange(RetrieveSubPages(pages[i].Id)); 
    } 
1

的foreach使用枚舉。 您使用foreach循環的集合必須實現IEnumerable(或IEnumerable<T>)。 然後,foreach調用該集合的GetEnumerator方法,並使用Enumerator遍歷集合。

4

在大多數情況下,foreach針對活動集合(沒有顯式克隆),並且如果您在枚舉枚舉時嘗試更改集合,則枚舉數將打破一個例外。因此,如果您添加到Pages,預計會出現問題。

5

看起來代碼不會修改Pages集合,而是Pages集合中Page對象中的對象內容。至少具有類似方法的Page類型。

通常,每個集合中的適合於本身的方式實現了迭代和通常變得而迭代不可修改的,但人們可以通過利用本身的快照implelment該迭代的集合。

沒有任何機制來從一個循環,這將允許採取行動,在這一點上(考慮如何做到這一點有例外互動,斷裂,在循環體返回)採取檢測退出。

0

我敢肯定你會得到抱怨底層集合被修改

1

你是不是修改你枚舉集合拋出的異常,所以你不會有這個代碼的任何問題。

這也是無關緊要的,如果集合的克隆被列舉,因爲對象包含雙方,收集和克隆,仍然是相同的(參考值等於)。

2

我認爲最保險的做法是這樣的:

Array<Page> newpages = new Array<Page>();  
foreach(Page page in pages) 
{ 
    newpages.AddRange(RetrieveSubPages(page.Id)); 
} 

pages.AddRange(newpages); 

你不得不延長這個有點如果你想遞歸到子頁面。

相關問題