我正在尝试在迭代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);
}
}
答案 0 :(得分:20)
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<Gem>
OnGemCollected(gem.Value, Player);
}
}
例如,如果它是dictionary<string, Gem>
,您可以像这样迭代:
foreach(string s in gems.Keys.ToList())
{
if(gems[s].BoundingCircle.Intersects(Player.BoundingRectangle))
{
gems.Remove(s);
}
}
答案 1 :(得分:1)
正如其他答案所说,foreach的设计纯粹是为了迭代集合而不将其修改为per the documenation:
foreach语句用于遍历集合以获取 所需信息,但不应用于更改内容 该系列旨在避免不可预测的副作用。
为了做到这一点,您需要使用for loop(存储您需要删除的集合的项目),然后将其从集合中删除。
但是,如果您使用List<T>
,则可以执行此操作:
lines.RemoveAll(line => line.FullfilsCertainConditions());
答案 2 :(得分:1)
最简单的方式是做@ IV4建议:
foreach (var gem in gems.ToList())
ToList()
会将字典转换为KeyValuePair
的列表,因此它可以正常工作。
你不想这样做的唯一一次就是如果你有一个大字典,你只需要删除相对较少的项目,并且你想减少内存使用。
只有在这种情况下,您才想使用以下方法之一:
在找到密钥时列出密钥,然后有一个单独的循环来删除项目:
List<KeyType> keysToRemove = new List<KeyType>();
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()
之前移除很重要,那么(使用键类型TKey
和值类型TValue
)执行此操作像这样:
var itemsToRemove = new List<KeyValuePair<TKey, TValue>>();
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);
}
答案 3 :(得分:0)
您应该使用for循环而不是foreach循环。请参阅here
答案 4 :(得分:0)
集合使用Enumarator支持foreach语句。枚举器可用于读取集合中的数据,但不能用于修改基础集合。如果对集合进行了更改,例如添加,修改或删除元素,则枚举数将无法恢复,并且下一次调用MoveNext或Reset会引发InvalidOperationException。 用于循环以进行集合修改。