• This is a read only backup of the old Emudevs forum. If you want to have anything removed, please message me on Discord: KittyKaev

Collection was modified...

Mathias

Exalted Member
This error is bugging me it really dosnt matter as the thing i am doing works as it should but i dont want it

codeSnippet:
Code:
    void CurrentDeckGUI(int id) {
        scrollPosition2 = GUILayout.BeginScrollView(scrollPosition2, GUILayout.Width(300), GUILayout.Height(Screen.height - 5));
		List<Card> tempList = gm.currentDeck;
		
		foreach (Card card in tempList) {
            GUILayout.Label("");
            if (GUILayout.Button(gm.AssignTextureToCard(card))) {
                if (gm.currentDeck.Count > 0) {
                    gm.currentDeck.Remove(card);
                    gm.availableCards.Add(card);
                }

            }
        }
        GUI.EndScrollView();


    }

How would i not get the Collection was modified here? i tried a few diffrent things but dont seem to find a way to fix it

what i did find is that most people say i should change the foreach to for so its like
Code:
for(int x=0;x<tempList.Count;x++)
but i would hope there is a way to use foreach
 
Last edited:

Evilfairy

Enthusiast
The collection used in a foreach loop is immutable by design. If you want to modify the items in a collection, use a for loop.
 

neglected

Enthusiast
The real answer here is that you don't understand how reference types work. The reason you are getting the CollectionModifiedException is that the collection you are enumerating over has been modified during the enumeration of said collection.
You've taken the correct approach of creating a temporary copy of the deck list and you will then assign the temporary copy to the real list after the enumeration ends.
However unfortunately when you create the temporary list you are simply doing this:

Code:
		List<Card> tempList = gm.currentDeck;
This doesn't work because all collections are reference types. This means that the field storing that variable is actually a reference to where the variable actually is in memory. By doing that line above you are not creating a copy of the gm.currentDeck collection, you are instead creating a new variable that points to the same location as the gm.currentDeck field. This means that when you iterate over tempList and then remove from gm.currentDeck, you are in actuality iterating over the same sequence in memory.

In order to resolve this issue, just do this instead:
Code:
		List<Card> tempList = new List<Card>(gm.currentDeck);
This will create a new list that is independent of the current deck list while maintaining all of it's values. This means that you can iterate over tempList and modify gm.currentDeck at the same time with no issues.

I would recommend, however, that you make this an atomic operation (I.e, don't modify gm.currentDeck until you've made all the necessary modifications somewhere else first). Also note that the constructor I linked carries a speed of O(N) in best case scenarios - this means that it will take proportionally longer the more elements you have in the original list. Need to bear that in mind if you have a lot of elements.
 
Last edited:
Top