Интеллектуальный способ удаления элементов из списка < T> при перечислении в C #

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

List<int> myIntCollection = new List<int>();
myIntCollection.Add(42);
myIntCollection.Add(12);
myIntCollection.Add(96);
myIntCollection.Add(25);

foreach (int i in myIntCollection)
{
    if (i == 42)
        myIntCollection.Remove(96);    // The error is here.
    if (i == 25)
        myIntCollection.Remove(42);    // The error is here.
}

В начале итерации после того, как происходит изменение, возникает InvalidOperationException , потому что счетчикам не нравится, когда изменяется базовая коллекция.

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

  1. Не удаляйте внутри этого цикла, вместо этого сохраните отдельный «Список удаления», который вы процесс после основного цикла.

    Обычно это хорошее решение, но в моем случае мне нужно, чтобы предмет исчез немедленно, так как «жду» до основной цикл реального удаления элемента изменяет логический поток моего кода.

  2. Вместо удаления элемента просто установите флаг на элементе и отметьте его как неактивный. Затем добавьте функциональность шаблона 1, чтобы очистить список.

    Этот будет работать для всех моих нужд, но это означает, что партия кода должна будет измениться, чтобы проверять неактивный флаг каждый раз, когда осуществляется доступ к элементу. На мой взгляд, это слишком много администрирования.

  3. Каким-то образом включить идеи шаблона 2 в класс, унаследованный от List . Этот суперсписок будет обрабатывать флаг неактивности, удаление объектов постфактум, а также не будет предоставлять элементы, отмеченные как неактивные, для потребителей перечисления. По сути, он просто инкапсулирует все идеи шаблона 2 (а затем и шаблона 1).

    Существует ли такой класс? У кого-нибудь есть код для этого? Или есть способ лучше?

  4. Мне сказали, что доступ к myIntCollection.ToArray () вместо myIntCollection решит проблему и позволит мне удалить внутри цикла.

    Мне это кажется плохим шаблоном проектирования, или, может быть, все в порядке?

Подробности:

  • В списке будет много элементов, и я буду удалять только некоторые из них.

  • Внутри цикла я будет выполнять всевозможные процессы, добавлять, удалять и т. д., поэтому решение должно быть достаточно общим.

  • Элемент, который мне нужно удалить , может не быть текущим элементом в цикле. Например, я могу находиться на элементе 10 цикла из 30 элементов, и мне нужно удалить элемент 6 или элемент 26. Из-за этого переход назад по массиву больше не будет работать. ; o (

83
задан Palec 1 March 2016 в 10:58
поделиться