2015-09-28 69 views
0

我最近一直在使用Foreach語句發現問題,並且在更改不應影響枚舉項的變量時拋出Collection was modified; enumeration operation may not execute異常,但它仍然存在。這裏是我的代碼,所以我可以繼續我的解釋:更改自變量時,枚舉可能不會執行異常

private static CEconTradeOffer RemoveUndesirables(CEconTradeOffer offer) 
    { 
     try 
     { 
      CEconTradeOffer returned = offer; 
      foreach (CEconAsset cEconAsset in offer.ItemsToReceive) 
      { 
       string marketHashName = cEconAsset.GetMarketHashName(_config.ApiKey); 
       if (marketHashName.ToLower().Contains("case") || 
        marketHashName.Contains("gut") || 
        marketHashName.Contains("falchion") || 
        marketHashName.Contains("bayonet") || 
        marketHashName.Contains("huntsman") || 
        marketHashName.Contains("karambit") || 
        marketHashName.Contains("butterfly")) 
       { 
        //somehow changes both "offer" and "returned" at once. 
        returned.ItemsToReceive.Remove(cEconAsset); 
        continue; 
       } 

       MarketValue value = MarketHandler.GetPriceOverview(Convert.ToUInt32(cEconAsset.AppId), 
        marketHashName); 
       if (!value.Success || int.Parse(value.Volume, NumberStyles.AllowThousands) <= 20) 
        returned.ItemsToReceive.Remove(cEconAsset); 
      } 
      return returned; 
     } 
     catch (Exception e) 
     { 
      Write.Exception(e); 
      return null; 
     } 
    } 

這個功能被設計來完成它所說的;從交易報價中刪除不需要的項目。正如你所看到的,我設置了CEconTradeOffer returned等於名爲offer的相同類型的傳遞參數。奇怪的是,無論什麼時候我改變returned的內容,它都會導致foreach聲明中斷,即使我在技術上不應以任何方式影響offer.ItemsToReceivereturned是應該修改的。當我使用調試器時,我注意到在和offer兩處都發生了變化,線路returned.ItemsToReceive.Remove(cEconAsset);。通過我以前使用C#和瀏覽相關問題的經驗,這不應該發生,因爲我正在創建一個應該與offer分開的新變量。我試過包括設置returned等於new CEconTradeOffer()然後設置它等於offer,但無濟於事。在我對這個問題的研究中,我似乎只能發現人們無法創建新變量並在foreach聲明中修改該變量而不是枚舉值的問題。

有什麼明顯的我明白了嗎?我不明白爲什麼當我創建一個單獨的變量來更改foreach聲明中的這個特定問題時。

我沒有使用多個線程,所以它不能在自己的執行線程之外受到影響。

在此先感謝。

+0

AlexD在他的回答中指出了問題:'returned'是'offer',所以remove方法修改了集合,並且出現錯誤 - 在枚舉期間不要修改集合。 –

+1

有用的閱讀 - [淺vs深層複製](http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy) –

回答

4

每當我改變returned裏面的東西它會導致foreach聲明打破,即使我在技術上不應該以任何方式影響offer.ItemsToReceive

看來CEconTradeOffer是引用類型,所以後來分配

CEconTradeOffer returned = offer; 

你得到另一個參考完全一樣的東西。

因此,當使用returned.ItemsToReceive.Remove(cEconAsset)刪除項目時,它們將從同一個集合中刪除,只需通過另一個參考。

+0

I發現了它,但你首先到達那裏:P –

+0

啊,好的。有沒有辦法糾正這個問題? –

+1

@ChrisAltig我沒有檢查邏輯。但是如果你想在枚舉時修改一個集合,你可以使用普通的for循環。 (如果刪除項目可能會更容易從右到左運行,因此刪除項目不會影響其餘項目。) – AlexD

相關問題