- Home /
How can I set a dictionary value in foreach loop?
Dictionary<BuffType, (BuffType type, int value, float time)> activeBuffList = new Dictionary<BuffType, (BuffType type, int value, float time)>();
foreach (var activeBuff in activeBuffList)
{
(BuffType type, int value, float time) v = activeBuff.Value;
v.time -= Time.deltaTime;
activeBuffList[activeBuff.Key] = v;
}
it pop up some error:collection was modified enumeration operation may not execute. c# dictionary in
activeBuffList[activeBuff.Key] = v;
thankyou for your help~
Answer by Bunny83 · Jul 02, 2020 at 11:21 AM
You simply can't when you use unnamed tuples. Unnamed tuples are structs and therefore need to be assigned / copyied back into the dictionary. However The IEnumerator used to iterate through the dictionary will throw an exception whenever the content of the dictionary has changed.
You have several options:
replace your unnamed tuple with an actual class. That way you don't have to assign it back into the dictionary.
The other option is that you create a temp list / array of the content of your dictionary and iterate over that instead. The easiest way to do that for a dictionary is to use the Linq extension "ToList". So you add
using System.Linq;
at the top and you can do this
foreach (var activeBuff in activeBuffList.ToList())
instead. So ToList will copy the content into a List which is used in the foreach loop. The rest of your code stays the same. This way the foreach loop doesn't care about any changes in the dictionary. However I would strongly recommend to use the first approach and exchanging the unnamed tuple with a class. That way you can simply change a value inside the class without the need of assigning it back
foreach (var activeBuff in activeBuffList)
{
var v = activeBuff.Value;
v.time -= Time.deltaTime;
}
Of course as I mentioned this requires that your "value" is an actual class. Something like this:
public class Buff
{
public BuffType type;
public int value;
public float time;
}
Your dictionary would look like this:
Dictionary<BuffType, Buff> activeBuffList = new Dictionary<BuffType, Buff>();
Of course we don't know how you actually populate your dictionary. But if should be obvious that you have to create those "Buff" instances when you want to add them to the dictionary.
Your answer
Follow this Question
Related Questions
How do I create a variable for each GameObject that I added to an array by using a loop? 2 Answers
C# Dictionary protection level when foreach-ing 1 Answer
Similar set of variables between classes... 2 Answers
Set variable in script from a different script... 3 Answers
Field Initializer Error 1 Answer