如何在C#中迭代Collection时添加或删除对象

我在迭代Collection时尝试删除对象。 但我得到例外。 我怎样才能做到这一点? 这是我的代码:

foreach (var gem in gems) { gem.Value.Update(gameTime); if (gem.Value.BoundingCircle.Intersects(Player.BoundingRectangle)) { gems.Remove(gem.Key); // I can't do this here, then How can I do? OnGemCollected(gem.Value, Player); } } 

foreach设计用于迭代集合而无需修改它。

要在迭代时从集合中删除项目,请使用从结尾到开头的for循环。

 for(int i = gems.Count - 1; i >=0 ; i--) { gems[i].Value.Update(gameTime); if (gems[i].Value.BoundingCircle.Intersects(Player.BoundingRectangle)) { Gem gem = gems[i]; gems.RemoveAt(i); // Assuming it's a List OnGemCollected(gem.Value, Player); } } 

例如,如果它是dictionary ,您可以像这样迭代:

 foreach(string s in gems.Keys.ToList()) { if(gems[s].BoundingCircle.Intersects(Player.BoundingRectangle)) { gems.Remove(s); } } 

正如其他答案所说,foreach被设计为纯粹用于迭代集合而不根据文档修改它:

foreach语句用于迭代集合以获取所需信息,但不应用于更改集合的内容以避免不可预测的副作用。

为了做到这一点,你需要使用for循环 (存储你需要删除的集合的项目),然后从集合中删除它们。

但是,如果您使用List ,则可以执行以下操作:

 lines.RemoveAll(line => line.FullfilsCertainConditions()); 

最简单的方法是做@ IV4建议的事情:

 foreach (var gem in gems.ToList()) 

ToList()会将Dictionary转换为KeyValuePair列表,因此它可以正常工作。

你不想这样做的唯一一次是你有一个大字典,你只需要删除相对较少的项目,并且你想减少内存使用。

只有在这种情况下,您才想使用以下方法之一:


在找到密钥时列出密钥,然后有一个单独的循环来删除项目:

 List keysToRemove = new List(); foreach (var gem in gems) { gem.Value.Update(gameTime); if (gem.Value.BoundingCircle.Intersects(Player.BoundingRectangle)) { OnGemCollected(gem.Value, Player); keysToRemove.Add(gem.Key); } } foreach (var key in keysToRemove) gems.Remove(key); 

(其中KeyType是您正在使用的键的类型。替换正确的类型!)

或者,如果调用OnGemCollected() 之前删除gem很重要,那么(使用键类型TKey和值类型TValue )执行如下操作:

 var itemsToRemove = new List>(); foreach (var gem in gems) { gem.Value.Update(gameTime); if (gem.Value.BoundingCircle.Intersects(Player.BoundingRectangle)) itemsToRemove.Add(gem); } foreach (var item in itemsToRemove) { gems.Remove(item.Key); OnGemCollected(item.Value, Player); } 

您应该使用for循环而不是foreach循环。 请参考这里

集合使用Enumarator支持foreach语句。 枚举器可用于读取集合中的数据,但不能用于修改基础集合。 如果对集合进行了更改,例如添加,修改或删除元素,则枚举数将无法恢复,并且下一次调用MoveNext或Reset会引发InvalidOperationException。 用于循环以进行集合修改。