我最近一直有一个问题与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.ItemsToReceive
。returned
是需要修改的。当我使用调试器时,我注意到returned
和offer
都在returned.ItemsToReceive.Remove(cEconAsset);
行更改。根据我以前使用c#和浏览相关问题的经验,这应该不会发生,因为我正在创建一个应该与offer
分开的新变量。我试过将returned
设置为new CEconTradeOffer()
,然后将其设置为offer
,但无济于事。在我对这个问题的研究中,我似乎只能发现人们不能在foreach
语句中创建一个新变量并修改它,而不是在枚举值中修改它的问题。
有什么明显的我错过了吗?我不太明白为什么当我创建一个单独的变量来改变foreach
语句时,我会得到这个特定的问题。
我没有使用多个线程,所以它不会在自己的执行线程之外受到影响。
每当我改变
returned
内部的东西时,它会导致foreach
语句中断,即使我技术上不应该以任何方式影响offer.ItemsToReceive
。
似乎CEconTradeOffer
是一个引用类型,所以你分配
CEconTradeOffer returned = offer;
你会得到另一个对完全相同事物的引用
所以当使用returned.ItemsToReceive.Remove(cEconAsset)
删除项目时,它们将从同一集合中删除,只是通过另一个引用。