嗨我遇到for
循环问题。
看起来像这样
for (int i = 0; i < ObjectManager.Instance.Objects.Count; i++)
{
if (ObjectManager.Instance.Objects[i] is Asteroid)
{
ObjectManager.Instance.Objects.Remove(ObjectManager.Instance.Objects[i]);
}
}
但是当我删除对象时,计数会变短,导致循环过早结束。有没有办法在没有一堆额外循环的情况下做到这一点。
答案 0 :(得分:8)
为什么不循环向后?
// Just change the order from Count - 1 down to 0
for (int i = ObjectManager.Instance.Objects.Count - 1; i >= 0; --i)
{
if (ObjectManager.Instance.Objects[i] is Asteroid)
{
ObjectManager.Instance.Objects.Remove(ObjectManager.Instance.Objects[i]);
}
}
如果您必须循环转发(例如,如果实例应按创建顺序删除,因为它们相互依赖),您可以修改for循环这样:
for (int i = 0; i < ObjectManager.Instance.Objects.Count;) // <- No increment here
if (ObjectManager.Instance.Objects[i] is Asteroid)
ObjectManager.Instance.Objects.Remove(ObjectManager.Instance.Objects[i]);
else
i += 1; // <- Increment should be here!
另一种可能性是 Linq :
ObjectManager.Instance.Objects.RemoveAll(item => item is Asteroid);
答案 1 :(得分:4)
三个选项:
如果ObjectManager.Instance.Objects
是List<T>
,请将List<T>.RemoveAll
与谓词一起使用,使您的代码更多更简单:
// This replaces your whole loop...
ObjectManager.Instance.Objects.RemoveAll(x => x is Asteroid);
从集合的 end 计算,而不是从开始计算,这样您之后就不需要调整索引了:
for (int i = ObjectManager.Instance.Objects.Count - 1; i >= 0; i--)
调用i
后,只需递减Remove
,以便在下一次迭代时查看正确的索引。
请注意,在第二个和第三个选项中,如果将表达式ObjectManager.Instance.Objects
提取到局部变量中,则在使用它4次之前,您的代码将更容易阅读。另请考虑使用RemoveAt(i)
而不是Remove(instances[i])
,假设RemoveAt
适用于您正在使用的类型。