Click to See Complete Forum and Search --> : Problems with moving objects around in a 2d array


Purple-Yin
October 6th, 2009, 06:20 PM
Hi, I’m trying to get some objects to move around in a 2d array of lists, but the program keeps exiting with ‘System.InvalidOperationException’ and “Additional information: Collection was modified; enumeration operation may not execute.”


I’m pretty sure that this is the part of the code causing all the problems-

public void cycleThroughList()
{
for (int x = 0; x < GridDimention; x++)
{
for (int y = 0; y < GridDimention; y++)
{
foreach (Microbe i in theWorld[x, y])
{
i.Talk();
Update_Position(i);

}
}
}
}

public void Update_Position (Microbe m)
{
if (m.sX != 0 & m.sY != 0)
{
theWorld[m.positionX, m.positionY].Remove (m);
theWorld[m.positionX + m.sX, m.positionY + m.sY].Add (m);
}

m.Talk();
}

Where ‘Talk’ is a method that writes to the console the coordinates of the Microbe object, and the ‘int sX’ and ‘int sY’ are the modifications to the objects location on the array.

Do you guys have any idea how to fix this?
I really appreciate any advice you can give me!

rliq
October 6th, 2009, 06:25 PM
You are not allowed to modify items in a collection that is used in a foreach loop. As the code will lose track of where it is in the loop. However... for (Int32 i = 0; i < XX; i++) will work fine.

BigEd781
October 6th, 2009, 06:27 PM
You are invalidating the state of the iterator by modifying the collection. You can't do that. How would you expect the iteration to continue in a normal fashion? Even if that sort of thing were allowed you would end up missing some objects and modifying others more than once. You should iterate through first and add the items to modify to a separate collection and then iterate through that modifying the original. That, or use one of the extension methods that take a delegate as the parameter to find all items that meet some criteria.

You are not allowed to modify items in a collection that is used in a foreach loop. As the code will lose track of where it is in the loop. However... for (Int32 i = 0; i < XX; i++) will work fine.

It will not 'work fine', it will just not throw an error. The iteration will still produce the wrong result.

rliq
October 6th, 2009, 07:58 PM
I've done this before, as long as you don't alter the loop counter variable (which works but not best practice) I have never had a problem.

If you have a list or array of stuff and you need to modify each one, how do you do it in a loop?

In case we are a talking with crossed lines:

foreach (MyObject obj in myObjectList)
obj.UpdateObject(); // fails

for (Int32 i = 0; i < myObjectList.Length; i++)
myObjectList[i].UpdateObject(); // succeeds

ahh I see this guy was talking about moving the objects around... point taken.

BigEd781
October 6th, 2009, 08:24 PM
Yeah, it's analogous to something like, this, which will not do what it seems...


List<int> collection = new List<int>( new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } );
for (int i = 0; i < collection.Count; ++i )
{
collection.Remove( collection[i] );
}

Console.Write( collection.Count ) // prints "4"

You will miss some there. You can always use a for loop to iterate backwards through the collection though.