#c# #.net
#c# #.net
Вопрос:
foreach (string key in dbFields.Keys)
dbFields[key] = MySqlHelper.EscapeString(dbFields[key]);
Я получаю ошибку InvalidOperationException, утверждающую, что коллекция была изменена. Почему он думает, что коллекция ключей была изменена?
Я просто хочу применить функцию ко всем значениям словаря -_-
Я знаю, что смогу это сделать, если использую второй словарь. Мне просто интересно, существует ли строгий упрощенный элегантный способ изменить все значения в словаре (без явного создания второго).
Ответ №1:
Попробуйте это:
foreach (string key in dbFields.Keys.ToList())
dbFields[key] = MySqlHelper.EscapeString(dbFields[key]);
Вы не можете изменять коллекцию, по которой выполняете итерацию, ToList()
в этом случае для вас будет создана новая List<string>
, по которой вы выполняете итерацию, поэтому вы можете безопасно изменять словарь.
Что касается комментария — из MSDN:
Словарь.Сбор ключей — это не статическая копия; вместо этого словарь.KeyCollection ссылается обратно на ключи в исходном словаре. Следовательно, изменения в словаре продолжают отражаться в словаре.Сбор ключей.
Таким образом, это зависит от реализации индексатора ( dbFields[key] = ...
), считает ли словарь, что коллекция ключей изменена (очевидно, это так, поскольку есть исключение) — к сожалению, у меня нет Reflector под рукой в данный момент, иначе я мог бы просто проверить.
Комментарии:
1. Что меня смущает — разве коллекция ключей не отличается от коллекции значений?
2. Когда можно изменить коллекцию ключей, присвоив значение с помощью dbFields[newkey]. поэтому при выполнении такого назначения вы получаете исключение.
3. @Volkmar — технически это не новый ключ, хотя он изменяет значение для существующего ключа.
4. Настройка через индексатор вызывает into
set_Item
, который вызывает INTOInsert
, и именно здесь я теряюсь в IL. У меня также нет Reflector на моей машине.