Removing Items From A Container In A Foreach Loop

It wouldn’t have been unrealistic for the designers of .NET to find a way to make this work:

foreach( Item i in ItemList )
{
  if( i.ShouldBeRemoved )
  {
    ItemList.Remove(i);
  }
}

What happens is you get a ‘collection modified’ exception and you’re hosed. You can’t move to the next item in the list because removing the item broke the list. It wouldn’t have been that hard for the design of IEnumerable (the thingy that makes foreach possible) to keep track of where the next item was even after a removal.

Instead of being able to use the above code, something like this clunky bit is required:

for( int i = (ItemList.Count – 1); i >= 0; i– )
{
  if( i.ShouldBeRemoved )
  {
    ItemList.Remove(i);
  }
}

It’s like telling someone they can avoid head-on car collisions by always driving in reverse.

Anyhow, there was a bit of a problem with the Select() command and socket management, and this was the solution. The socket code is now functional and stable enough that I can log in and run around trying to play the game. It’s not terribly playable yet — I have a *LOT* more work to do, but it’s still theoretically possible that a development server could go up i mid-but-more-likely-late May.

3 Comments

  • Peter says:

    Doing this is very easy with List.RemoveAll(Predicate) and lambda expressions. For a list of integers List, removing everything between 8 and 15 is as simple as doing:

    List.RemoveAll(i => i > 8 && i < 15);

    The collection handles the removal of everything in the list that matches the predicate. The predicate is a lambda expression here – a type of anonymous function. In this case the anonymous function takes one parameter (whose type is inferred from the generic list’s type) and returns a bool.

    A short introduction to lambda expressions can be found at http://msdn2.microsoft.com/en-us/library/bb397687.aspx .

  • Xangis says:

    Nice. Lambda expressions are pretty useful, but I don’t think they’ll work here yet since we’re going to be running the server side using Mono on Ubuntu. As far as I can tell nothing newer than .NET 2.0 is stable on *NIX.

  • VĂ©ronique says:

    Every coder should know that you can’t use a for loop if you’re going to modify the number of items in that for loop!! Even if you’re checking against the actual number of items in a list at each iteration, you can still get yourself in trouble if you don’t play with the iterator yourself.

    You know, that’s why while loops were invented. Use them.

    Why in the world are you using .NET. That’s another question. Though Microsoft is pushing C# big time, C++ isn’t going away anytime soon.