PrimuS PrimuS - 23 days ago 5
C# Question

Deserialized jsonObject gets updated, foreach then fails

I have a json File that I deserialize with Newtonssoft Json.Net like this:

/* Get current config */
dynamic json = JsonConvert.DeserializeObject<Speaker>(
File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "cfg\\speaker.json"));

dynamic jsonDevice = json.DeviceList;

/* Go through the List */
foreach (Tapi tapi in lvTapiSonos.Items)
{
foreach (var line in jsonDevice)
{
foreach (var l in line)
{
/* If not in List already, add it */
if (l.Key != tapi.Name)
{
/* Add to Config */
json.DeviceList.Add(new Dictionary<string, List<Device>>
{
{
tapi.Name,
new List<Device>
{
new Device
{
Volume = "5",
Ip = currentEditIp,
Name = currentEditName
}
}
}
});
}
}
}
}
string output = JsonConvert.SerializeObject(json, Formatting.Indented);
File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "cfg\\speaker.json", output);


Unfortunately that only works for the first
foreach
as I get an exception "The List has changed. Enumeration cannot be continued," (similar as I have it in german) in the line
foreach (var line in jsonDevice)
.

I understand this means, that the
jsonDevice
has been updated (it shows now one more item in debug), but since I assigned
jsonDevice
outside of the foreach, how is it updated? Having
foreach var line in json.DeviceList
produce and error seems logical as I update the json Object inside the foreach, but why does this still happen?

Any hint appreciated...

Answer

The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop. http://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx

As explained you can use for loop for your usecase. but if you call ToList() or ToArray you can get copy of items which can be use for iterate

dynamic jsonDevice = json.DeviceList.ToList();