for loop ends prematurely when objects are removed

Hi I have a problem with a for loop.

It looks like this

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]);
   }
}

But the count gets shorter while I remove objects, which causes the loop to end prematurely. Is there a way to do this without a bunch of extra loops.

Jon Skeet
people
quotationmark

Three options:

  • If ObjectManager.Instance.Objects is a List<T>, use List<T>.RemoveAll with a predicate, making your code much simpler:

    // This replaces your whole loop...
    ObjectManager.Instance.Objects.RemoveAll(x => x is Asteroid);
    
  • Count from the end of the collection rather than from the start, so that you don't need to adjust the index afterwards:

    for (int i = ObjectManager.Instance.Objects.Count - 1; i >= 0; i--)
    
  • Just decrement i after calling Remove, so that you'll look at the right index on the next iteration.

Note that in the second and third options your code will be a lot simpler to read if you extract the expression ObjectManager.Instance.Objects into a local variable before you use it 4 times. Also consider using RemoveAt(i) rather than Remove(instances[i]), assuming RemoveAt is available for the type you're using.

people

See more on this question at Stackoverflow