在foreach中从List中删除元素

时间:2014-06-05 18:00:31

标签: c# xna

我有List<Buoy>,我想删除Buoy点击的Ship

foreach (var Chest in Chests) {
    if (Chest.Bounds.Intersects (Ship.Bounds)) {
        Player.Score += 1;
    }
}

我编写了Dispose() - 方法,我想将具体的Chest设置为null。如何在不收到错误的情况下执行此操作,因为它是一个foreach迭代变量,因为它是Chest

4 个答案:

答案 0 :(得分:4)

foreach很棒,但它确实有使迭代器不可变的不幸副作用。一种解决方法是使用另一个列表来跟踪要删除的Buoy

     List<Buoy> ChestsToRemove = new List<Buoy>();
     foreach (Buoy chest in Chests)
     {
        if (Buoy.Bounds.Intersects(Ship.Bounds))
        {
           Player.Score += 1;
           ChestsToRemove.Add(chest);
        }
     }
     foreach (Buoy chestToRemove in ChestsToRemove)
     {
        Chests.Remove(chestToRemove);
     }

答案 1 :(得分:4)

确实需要结合发现你与所有事物列表中的删除相交的事物。

var collisions = Chests.Where(c => c.Bounds.Intersects(Ship.Bounds)).ToList();
Player.Score += collisions.Count();
Chests = Chests.Except(collisions);

答案 2 :(得分:1)

你也可以像下面的例子那样删除

foreach (var Chest in Chests) {
    if (Chest.Bounds.Intersects (Ship.Bounds)) {
        Player.Score += 1;
        Chest.IsActive = false;
    }
}

Chests.RemoveAll(c => !c.IsActive)

答案 3 :(得分:0)

当你想要从你重复的列表中删除项目时,问题是枚举器会丢失你在列表中的位置。

这有点像锯你所坐的树枝。你不应该这样做,因为它会有未被发现的行为。

现在,如何解决这个问题?

很容易,你需要复制你的清单,迭代你的副本,并从原始清单中删除这些项目。

听起来很多代码,但您唯一需要做的就是在foreach语句中添加ToList()

像这样:

foreach (var Chest in Chests.ToList()) {
    if (Chest.Bounds.Intersects (Ship.Bounds)) {
        Player.Score += 1;
    }
}

现在,为什么这样做?

这是因为ToList()在内存中创建了列表的副本。所以基本上,你现在正在迭代集合的副本。

所以这个apporach应该有用。