在foreach循环中修改Dictionary的内容

本文关键字:Dictionary 修改 foreach 循环 | 更新日期: 2023-09-27 18:16:52

我试图在foreach循环中更新c# Dictionary的内容,当满足特定条件时。

foreach (KeyValuePair<int, Corpus_22_04_2014_StreetTable_Row> entry in id_StreetNameDictionary)
{
    if(something_happens())
    {
         Corpus_22_04_2014_StreetTable_Row r = entry.Value;
         //Modify r
         id_StreetNameDictionary[entry.Key] = r;
    }
}

这抛出一个InvalidOperationException声明"Collection was modified;不能执行枚举操作。"似乎不允许在foreach循环中修改Dictionary的内容。

有什么可能的解决方法?

在foreach循环中修改Dictionary的内容

您可以简单地在字典上使用ToList将每个键值对复制到列表中。然后迭代该列表,而不是Dictionary:

foreach (var entry in id_StreetNameDictionary.ToList())
{
    if(something_happens())
    {
         Corpus_22_04_2014_StreetTable_Row r = entry.Value;
         //Modify r
         id_StreetNameDictionary[entry.Key] = r;
    }
}

创建一个包含所有键的列表并迭代该列表。例如:

foreach (var key in id_StreetNameDictionary.Keys.ToList())
{
    if(something_happens())
    {
         var r = id_StreetNameDictionary[key];
         //Modify r
         id_StreetNameDictionary[key] = r;
    }
}

这比从字典中创建一个KeyValuePair结构的列表更节省内存。

既然看起来您真的想修改而不一定是Dictionary,那么直接这样做:

foreach (var entry in id_StreetNameDictionary)
{
    if (something_happens())
    {
        ((Corpus_22_04_2014_StreetTable_Row)entry.Value)["FieldToChange"] = newValue;
        //...repeat for each field to change...you will be altering the row directly, no need to reassign it
    }
}

我使用下面的解决方法。也许不是很有效,但它确实有效。我声明了三个字典:

Dictionary<int, Corpus_22_04_2014_StreetTable_Row> id_StreetNameDictionary = new Dictionary<int, Corpus_22_04_2014_StreetTable_Row>();
Dictionary<int, Corpus_22_04_2014_StreetTable_Row> tempDictionary = new Dictionary<int, Corpus_22_04_2014_StreetTable_Row>();
Dictionary<int, Corpus_22_04_2014_StreetTable_Row> swapBuffer;

我完全转储了旧字典,所有修改和未修改的键/值对,到tempDictionary。然后交换两个字典并清除未使用的字典:

foreach (var entry in id_StreetNameDictionary)
{
    Corpus_22_04_2014_StreetTable_Row row = id_StreetNameDictionary[entry.Key];
    if (something_happens())
    {
        //Modify row
    }
    tempDictionary.Add(row.id, row);
}
swapBuffer = tempDictionary;
tempDictionary = id_StreetNameDictionary;
id_StreetNameDictionary = swapBuffer;
tempDictionary.Clear();