Можно ли изменить список во время итерации через него?

У меня есть следующее:

foreach (var depthCard in depthCards)
{
    var card = InternalGetCard(db, depthCard.CardId);
    var set = InternalGetSet(db, (int)card.ParentSetId);
    var depthArray = InternalGetDepthArrayForCard(db, set.SetId);
    foreach (var cardToUpdate in set.Cards)
    {
        // do stuff
        SaveChanges(db);
        depthCards.Remove(depthCardToUpdate); // since I already took care of it here, remove from depthCards
    }
}

Это не работает, хотя, потому что я изменяю коллекцию в середине цикла. Мой вопрос... есть ли какой-то тип коллекции, который разрешает этот тип доступа?

Я не хочу ToList() depthCards потому что у меня уже есть, и я хочу изменить этот список во время итерации. Является ли это возможным?

Ответ 1

Возможно, трюк заключается в повторении итерации назад:

for (int i = depthCards.Count - 1; i >= 0; i--) {
  if (depthCards[i] == something) { // condition to remove element, if applicable
     depthCards.RemoveAt(i);
  }
}

Ответ 2

Вы можете выполнить повторение с помощью for -loop

for (int i = depthCards.Count - 1; i >= 0; i--)
{
    depthCards.RemoveAt(i);
}

Вы также можете использовать List.ForEach, который позволяет изменять список на итерации:

depthCardToUpdate.ForEach(dc => depthCardToUpdate.Remove(dc));   

или если вы просто хотите удалить элементы при условии, используйте List.RemoveAll:

depthCardToUpdate.RemoveAll(dc => conditionHere);

Ответ 3

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

Смотрите: http://www.codeproject.com/Articles/28963/Custom-Enumerators