Вопрос

Давайте начнем со следующего фрагмента:

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);
  ..
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top