在foreach中删除通用列表中的项目

时间:2013-08-30 16:34:41

标签: c#

我现在正在为拾取器(硬币等)编码,但是当你拿起东西时...它不再在地面上了。

但我得到一个例外:System.InvalidOperationException。由map.Remove()引起,并由foreach循环抛出。

那么,如何从列表中正确删除拾取器?

foreach (CollisionTiles tile in map.CollissionTiles)
{
    if (!tile.isTransparant)
        player.Collision(tile.Rectangle, map.Width, map.Height);
    else
    {
        if (player.PickUp(tile, map.Width, map.Height))
            map.Remove(tile);
    }

    camera.Update(player.Position, map.Width, map.Height);
}

map.Remove()无效:

public void Remove(CollisionTiles tile)
{
    this.collissionTiles.Remove(tile);
}

2 个答案:

答案 0 :(得分:9)

最简单的方法是记住要删除的所有元素,然后将其删除:

var tilesToRemove = new List<CollisionTiles>();
foreach (var tile in map.CollisionTiles)
{
    if (!tile.IsTransparent)
    {
        player.Collision(tile.Rectangle, map.Width, map.Height);
    }
    else if (player.PickUp(tile, map.Width, map.Height))
    {
        tilesToRemove.Add(tile);
    }
    camera.Update(player.Position, map.Width, map.Height);
}

// Remove all the ones we didn't want
foreach (var tile in tilesToRemove)
{
    map.Remove(tile);
}
// Potentially call camera.Update here? We don't know if it uses the tiles

(顺便说一下,为什么你经常打电话给camera.Update还不清楚 - 在循环之后你能不能一次叫它吗?)

答案 1 :(得分:2)

使用for循环代替foreach

for (int i = map.CollisionTiles.Count - 1; i >= 0; i--)
{
    CollisionTile tile = map.CollisionTiles[i];
    if (!tile.isTransparant)
        player.Collision(tile.Rectangle, map.Width, map.Height);
    else
    {
        if (player.PickUp(tile, map.Width, map.Height))
            map.Remove(tile);
    }

    camera.Update(player.Position, map.Width, map.Height);
}