Tenho o caso clássico de tentar remover um item de uma coleção enquanto o enumera em um loop:
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.
}
No início da iteração, após uma mudança ocorrer, um InvalidOperationException
é lançado, porque os enumeradores não gostam quando a coleção subjacente muda.
Preciso fazer alterações na coleção durante a iteração. Existem muitos padrões que podem ser usados para evitar isso , mas nenhum deles parece ter uma boa solução:
Não exclua dentro deste loop; em vez disso, mantenha uma “Lista de Exclusão” separada, que você processa após o loop principal.
Normalmente, essa é uma boa solução, mas no meu caso, preciso que o item desapareça instantaneamente, pois "esperar" até que o loop principal realmente exclua o item altera o fluxo lógico do meu código.
Em vez de excluir o item, basta definir um sinalizador no item e marcá-lo como inativo. Em seguida, adicione a funcionalidade do padrão 1 para limpar a lista.
Isso iria trabalhar para todas as minhas necessidades, mas isso significa que um monte de código terá que mudar a fim de verificar a bandeira inativo sempre que um item é acessado. Isso é administração demais para o meu gosto.
De alguma forma, incorpore as idéias do padrão 2 em uma classe que deriva de
List<T>
. Esta Superlista tratará do sinalizador inativo, da exclusão de objetos após o fato e também não exporá os itens marcados como inativos aos consumidores de enumeração. Basicamente, ele apenas encapsula todas as idéias do padrão 2 (e subsequentemente do padrão 1).Existe uma classe como esta? Alguém tem código para isso? Ou há um modo melhor?
Disseram-me que acessar em
myIntCollection.ToArray()
vez demyIntCollection
resolverá o problema e me permitirá deletar dentro do loop.Isso parece um padrão de design ruim para mim, ou talvez seja bom?
Detalhes:
A lista conterá muitos itens e irei remover apenas alguns deles.
Dentro do loop, estarei realizando todos os tipos de processos, incluindo, removendo etc., portanto, a solução precisa ser bastante genérica.
O item que preciso excluir pode não ser o item atual no loop. Por exemplo, posso estar no item 10 de um loop de 30 itens e precisar remover o item 6 ou o item 26. Andar para trás pela matriz não funcionará mais por causa disso. ; o (