2009-07-14 452 views
8

基本上,我想在foreach循環內從列表中刪除一個項目。我知道這是可能的,當使用for循環,但爲了其他目的,我想知道這是否可以使用foreach循環實現。在c#中使用foreach循環時修改集合

a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 

for i in a: 
    print i 

    if i == 1: 
     a.pop(1) 

這讓下面的輸出

>>>1 
3 
4 
5 
6 
7 
8 
9 

但這樣做在C#中類似的東西的時候,我得到一個InvalidOperationException,我在想:

在Python中,我們可以通過以下步驟實現這一目標如果有解決這個問題的方法,而不只是簡單地使用for循環

在C#中的代碼,我使用時引發了異常:

static void Main(string[] args) 
    { 
    List<string> MyList = new List<string>(new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9"}); 

    foreach (string Item in MyList) 
    { 
    if (MyList.IndexOf(Item) == 0) 
     { 
     MyList.RemoveAt(1); 
     } 

    Console.WriteLine(Item); 
    } 
    } 

在此先感謝

回答

25

你不能做到這一點。從IEnumerator<T>的文檔:

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

替代品有:

  • 樹立項目的新的名單中刪除,然後將它們全部刪除之後
  • 使用正常的「for」循環,並確保你小心不去在相同的元素兩次或丟失任何。 (你說你不想這樣做,但你要怎樣做是行不通的。)
  • 建立僅包含要保留

元素的新集合最後這些備選方案之一是LINQ樣的解決方案,在這裏你通常書寫:

var newList = oldList.Where(x => ShouldBeRetained(x)).ToList(); 

(其中ShouldBeRetained是任何你想要的,當然,邏輯),以ToList()的調用是唯一必要的,如果你真的想它在一個列表中。這導致更多的聲明性代碼,這通常更易於閱讀。我不能輕易猜出你原來的循環是什麼意思(現在看起來很奇怪),而如果你可以純粹根據項目表達邏輯,它可以更清晰。

+0

我主要想知道我是否在某處使用了foreach實例,但如果它不能實現,至少現在已經確認!感謝你的回答 – ThePower 2009-07-14 09:04:12

1

當你使用foreach循環時,你絕對不能以任何方式更改集合。

您可以使用for循環併爲自己管理索引或製作集合的副本,並且在循環原始內容時,從副本中刪除等於原始內容中項目的項目。

在這兩種情況下,它都不太清楚或方便:)。

6

如果你需要的是刪除滿足條件的所有項目,你可以使用List<T>.RemoveAll方法:

List<string> MyList = new List<string>(new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9" }); 
MyList.RemoveAll(item => item == "1"); 

注意,這個修改初始列表。