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

Удалить внутри foreach с linq где

Я вижу, почему это не разрешено:

foreach (Thing t in myCollection) {
   if (shouldDelete(t) {
      myCollection.Delete(t);
   }
}

но как насчет этого?

foreach (Thing t in myCollection.Where(o=>shouldDelete(o)) {
   myCollection.Delete(t);
}

Я не понимаю, почему это не удается. Метод "Where()", очевидно, не возвращает исходную коллекцию, поэтому я не перечисляю вокруг исходной коллекции, когда пытаюсь удалить что-то из нее.

4b9b3361

Ответ 1

Я не понимаю, почему это не удается.

Я предполагаю, что ваш вопрос тогда "почему это не удается?" (Вы забыли на самом деле задать вопрос в своем вопросе.)

Метод "Where()", очевидно, не возвращает исходную коллекцию

Правильно. "Where" возвращает IEnumerable<T>, который представляет коллекцию с фильтром, помещенным поверх нее.

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

Неправильно. Вы перечисляете оригинальную коллекцию. Вы перечисляете исходную коллекцию с фильтром, помещенным поверх нее.

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

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

Ответ 2

Попробуйте использовать этот код

myCollection.RemoveAll(x => x.shouldDelete(x));

Ответ 3

Вы можете сделать:

myCollection.RemoveAll(shouldDelete);

Ответ 4

Второй оператор возвращает IEnumerable<>, действующий в вашем списке. Это должно быть хорошо:

foreach (Thing t in myCollection.Where(o=>shouldDelete(o).ToList()) {
   myCollection.Delete(t);
}

Ответ 5

Это потому, что сбор не следует изменять с помощью цикла foreach. Он пытается удалить его до выполнения всего цикла foreach. Следовательно, он потерпит неудачу.

Ответ 6

Где метод расширения фильтрует значения коллекции на основе переданного предиката и возвращает IEnumerable. Следовательно, не может изменять коллекцию во время итерации.

Вы можете использовать RemoveAll() для своей цели.