Tengo el caso clásico de intentar eliminar un elemento de una colección mientras lo enumero en un bucle:
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.
}
Al comienzo de la iteración después de que ocurre un cambio, InvalidOperationException
se lanza un, porque a los enumeradores no les gusta cuando cambia la colección subyacente.
Necesito hacer cambios en la colección mientras itero. Hay muchos patrones que se pueden usar para evitar esto , pero ninguno parece tener una buena solución:
No elimine dentro de este ciclo, en su lugar mantenga una "Lista de borrado" separada, que procesa después del ciclo principal.
Esta es normalmente una buena solución, pero en mi caso, necesito que el elemento desaparezca instantáneamente como "esperando" hasta que el bucle principal para eliminar realmente el elemento cambie el flujo lógico de mi código.
En lugar de eliminar el elemento, simplemente coloque una bandera en el elemento y márquelo como inactivo. Luego agregue la funcionalidad del patrón 1 para limpiar la lista.
Esto podría funcionar para todas mis necesidades, pero significa que una gran cantidad de código tendrá que cambiar con el fin de comprobar el indicador inactivo cada vez que se accede a un elemento. Esto es demasiada administración para mi gusto.
De alguna manera incorpore las ideas del patrón 2 en una clase de la que se deriva
List<T>
. Esta Superlista manejará la bandera inactiva, la eliminación de objetos después del hecho y tampoco expondrá los elementos marcados como inactivos a los consumidores de enumeración. Básicamente, solo encapsula todas las ideas del patrón 2 (y posteriormente del patrón 1).¿Existe una clase como esta? ¿Alguien tiene un código para esto? ¿O hay un mejor camino?
Me han dicho que acceder en
myIntCollection.ToArray()
lugar demyIntCollection
resolverá el problema y me permitirá eliminar dentro del bucle.Esto me parece un mal patrón de diseño, ¿o tal vez está bien?
Detalles:
La lista contendrá muchos elementos y solo eliminaré algunos de ellos.
Dentro del ciclo, haré todo tipo de procesos, agregar, eliminar, etc., por lo que la solución debe ser bastante genérica.
Es posible que el elemento que necesito eliminar no sea el elemento actual del bucle. Por ejemplo, puedo estar en el elemento 10 de un bucle de 30 elementos y necesito eliminar el elemento 6 o el elemento 26. Caminar hacia atrás a través de la matriz ya no funcionará debido a esto. ; o (