Изменение элемента в методе foreach
Вопрос
Давайте начнем со следующего фрагмента:
Foreach(Record item in RecordList){
..
item = UpdateRecord(item, 5);
..
}
Функция UpdateRecode изменяет некоторое поле элемента и возвращает измененный объект. В этом случае компилятор выдает исключение, говорящее, что элемент не может быть обновлен в итерации foreach. Р>
Теперь метод UpdateRecord изменен так, что он возвращает void, и фрагмент будет выглядеть следующим образом:
Foreach(Record item in RecordList){
..
UpdateRecord(item, 5);
..
}
В этом случае элемент будет обновлен, поскольку запись является ссылочным типом. Но это делает код нечитаемым.
В проекте, над которым я работаю, много циклов foreach с почти одинаковым кодом снова и снова, поэтому я хотел бы создать методы, которые обновляют части записей. Есть хороший способ сделать это? Тот, который делает код более читабельным, а не уничтожает его дальше?
Решение
Если вам нужно обновить коллекцию, не используйте шаблон итератора, как вы сказали, он либо подвержен ошибкам, либо плохо пахнет.
Я считаю, что использование цикла for с индексом немного яснее в этой ситуации, поскольку совершенно очевидно, что вы пытаетесь сделать таким образом.
Другие советы
Компилятор жалуется, что вы не можете обновить коллекцию , а не запись. Делая item = UpdateRecord, вы переназначаете переменную элемента итератора. Р>
Я не согласен с тем, что UpdateRecord (item, 5) никоим образом не читается - но если это заставляет вас чувствовать себя лучше, метод расширения может прояснить, что вы изменяете содержимое элемента.
static void Update(this Record item, int value) {
// do logic
}
foreach (Record item in RecordList) {
item.Update(5);
}
Вам нужно обновить тот же список? Не могли бы вы вместо этого вернуть новое (обновленное) перечисление?
foreach(Record item in RecordList){
..
yield return GetUpdatedRecord(item, 5);
..
}