我有List<Buoy>
,我想删除Buoy
点击的Ship
。
foreach (var Chest in Chests) {
if (Chest.Bounds.Intersects (Ship.Bounds)) {
Player.Score += 1;
}
}
我编写了Dispose()
- 方法,我想将具体的Chest
设置为null
。如何在不收到错误的情况下执行此操作,因为它是一个foreach迭代变量,因为它是Chest
。
答案 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应该有用。