Подтвердить что ты не робот

Изменение .NET-словаря при перечислении через него

Я использую словарь, и я хочу его изменить, пока я перечислил его, но, похоже, это не разрешено. Как я могу это сделать?

Спасибо

4b9b3361

Ответ 1

Вы должны сохранить ключ или объект, который хотите удалить, и разбить цикл, а затем использовать метод remove для удаления объекта из словаря.

Надеюсь, что это поможет

Ответ 2

Не, в принципе. Он явно не поддерживается. Из документов для Dictionary<,>.GetEnumerator():

Перечислитель остается в силе до тех пор, пока коллекция остается неизменной. Если в коллекцию внесены изменения, таких как добавление, изменение или удаление элементов, счетчик безвозвратно аннулирован и его поведение undefined.

Как правило, лучший способ - запомнить изменения, которые вы хотите сделать, а затем выполнить их впоследствии. Или вы можете взять копию словаря, чтобы начать с него, а затем повторить его, пока вы изменяете оригинал. Если бы вы могли предоставить нам больше информации о том, что вы пытаетесь сделать, это поможет.

Сказав это, новый класс ConcurrentDictionary в .NET 4.0 разрешает это, но результаты итерации не гарантируются - вы можете видеть изменения во время повтора, или вы не можете.

Ответ 3

Я ответил на здесь относительно очереди, но ответ тот же. Вы не можете перечислять с помощью foreach и изменять коллекцию одновременно.

Ответ 4

Я столкнулся с подобной ситуацией на работе. Мне нужно было изменить словарь, итеративно уменьшив его, пока у меня не осталось ключей/значений.

Я начал с создания списка ключей "для удаления", но это было очень медленным со всей другой логикой, которую я должен был реализовать. В качестве альтернативы, я закончил итерацию через словарь назад. Поскольку вы перемещаете словарь со спины к фронту, итерация не будет вызывать ошибку.

После того, как я выхожу из своей логики работы, она выглядит глупо, но я обещаю, что она работает и выглядит примерно так:

    Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
    while(dict.Any())
    {
        foreach(var key in dict.Keys.Reverse())
        {
            if(//conditional)
            {
                dict.Remove(key);
            }
            else
            {
                //do something with dict[key]
            }
        }
    }