У меня классический случай попытки удалить элемент из коллекции при его перечислении в цикле:
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.
}
В начале итерации после того, как происходит изменение, выдается an InvalidOperationException
, потому что перечислителям не нравится, когда изменяется базовая коллекция.
Мне нужно внести изменения в коллекцию во время итерации. Есть много шаблонов, которые можно использовать, чтобы избежать этого , но, похоже, ни один из них не имеет хорошего решения:
Не удаляйте внутри этого цикла, вместо этого сохраняйте отдельный «Список удаления», который вы обрабатываете после основного цикла.
Обычно это хорошее решение, но в моем случае мне нужно, чтобы элемент исчез немедленно, так как «ожидание» до тех пор, пока основной цикл действительно удалить элемент, изменит логический поток моего кода.
Вместо того, чтобы удалять элемент, просто установите для него флажок и отметьте его как неактивный. Затем добавьте функциональность шаблона 1, чтобы очистить список.
Это будет работать для всех моих потребностей, но это означает , что много коды придется изменить для того , чтобы проверить Недеятельную пометку каждый раз , когда пункт доступ. На мой взгляд, это слишком много администрирования.
Каким-то образом включить идеи паттерна 2 в класс, производный от
List<T>
. Этот суперсписок будет обрабатывать флаг неактивности, удаление объектов постфактум, а также не будет предоставлять элементы, отмеченные как неактивные, для потребителей перечисления. По сути, он просто инкапсулирует все идеи шаблона 2 (а затем и шаблона 1).Существует ли такой класс? У кого-нибудь есть код для этого? Или есть способ лучше?
Мне сказали, что доступ
myIntCollection.ToArray()
вместоmyIntCollection
решит проблему и позволит мне удалить внутри цикла.Мне это кажется плохим шаблоном проектирования, или, может быть, это нормально?
Детали:
В списке будет много пунктов, и я удалю только некоторые из них.
Внутри цикла я буду выполнять всевозможные процессы, добавлять, удалять и т. Д., Поэтому решение должно быть достаточно общим.
Элемент, который мне нужно удалить, может не быть текущим элементом в цикле. Например, я могу находиться на элементе 10 цикла из 30 элементов, и мне нужно удалить элемент 6 или элемент 26. Из-за этого переход назад по массиву больше не будет работать. ; o (