'Receiving an error, Collection was modified; enumeration operation may not execute, but I don't know what I am doing wrong and where?
Here is the code
List<Vector2Int> startPos = new();
startPos.Add(new(5, 5));
for (int i = 0; i < 2; i++)
{
var something = FloodFill(startPos);
foreach (KeyValuePair<Vector2Int, string> kv in something)
{
Debug.Log(kv.Key);
}
startPos.Clear();
List<Vector2Int> vector2Ints = new(something.Keys);
startPos = vector2Ints;
}
The above code is the code that I used and it's showing an error. Perhaps there is an error in the above part but for reference, I am also attaching the Floodfill function that I have written.
Dictionary<Vector2Int, string> FloodFill(List<Vector2Int> startPos)
{
Dictionary<Vector2Int, string> returnList = new();
foreach (Vector2Int pos in startPos)
{
returnList.Add(pos, "Anything");
}
List<Vector2Int> nextIterationList = new(startPos);
List<Vector2Int> tempList = new();
foreach (Vector2Int point in nextIterationList)
{
for (int m = 0; m < 3; m++)
{
tempList.Add(new(point.x - 1, point.y + (m - 1)));
tempList.Add(new(point.x + 1, point.y + (m - 1)));
if (m == 1)
{
continue;
}
tempList.Add(new(point.x, point.y + (m - 1)));
}
foreach (Vector2Int dot in tempList)
{
if (returnList.ContainsKey(dot))
{
tempList.Remove(dot);
}
else
{
returnList.Add(dot, "Anything");
}
}
}
return returnList;
}
The error that I am receiving is
Collection was modified; enumeration operation may not execute.
System.Collections.Generic.List1+Enumerator[T].MoveNextRare () (at <31c0f51ac5a24a22ba784db24f4ba023>:0) System.Collections.Generic.List
1+Enumerator[T].MoveNext () (at <31c0f51ac5a24a22ba784db24f4ba023>:0)
Solution 1:[1]
What's happening is that you alter the collection while iterating over it.
It makes sense this is not allowed, because, for example if you're sorting an array and insert elements while doing so this can lead to some confusing results or is hard/inconvenient to implement.
Looking at this:
foreach (Vector2Int dot in tempList)
{
if (returnList.ContainsKey(dot))
{
tempList.Remove(dot);
}
else
{
returnList.Add(dot, "Anything");
}
}
You are removing from tempList
while iterating it - effectively shorting the list, so; what to do with the enumerator position? Hence the error.
This could have been implemented but they choose not to.
As alternative you an use a reversed indexer for
to remove the element while enumerating the collection.
for (var i = tempList.Length - 1; i >= 0; i--)
Solution 2:[2]
You may want to switch to ConcurrentDictionary
see here Different behaviour when collection modified between Dictionary and ConcurrentDictionary
and here http://dotnetpattern.com/csharp-concurrentdictionary
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Gregory Bologna |