El codigo para este articulo aplica a C# 2.0
Una tarea mas o menos comun cuando usamos una lista generica, es borrar elementos de esta, vamos a ver que alternativas tenemos:
#1 La forma definitivamente equivocada de hacerlo:
List<Person> l1 = GetList();
//*** The wrong way
foreach (Person p in l1) {
if (p.Age > 30)
l1.Remove(p);
}
Este codigo nos dara una excepcion InvalidOperationException: "Collection was modified; enumeration operation may not execute."
#2 Funciona mas o menos (y nos permite ejecutar una accion en cada elemento que vamos a borrar)
List<int> ints = new List<int>();
ints.Add(1);
ints.Add(2);
ints.Add(3);
ints.Add(4);
ints.Add(5);
ints.Add(6);
ints.ForEach(delegate(int i) {
if ((i % 2) == 0) {
Console.WriteLine("removing"+i.ToString());
ints.Remove(i);
}
});
Si corres este codigo funcionara perfectamente, pero la verdad es que tiene un problema grande, si agregaras los numeros pares primero, verias que no los borra todos, y no te da una excepcion ni nada, simplemente se sale del foreach y continua; asi que este metodo funciona, pero solo en condiciones especiales, lo cual lo hace codigo peligroso
#3 La forma correcta: recorremos la coleccion hacia atras y borramos elementos cuando necesitamosint x = ints2.Count;
while (--x>=0) {
if (ints2[x] < 4)
ints2.RemoveAt(x);
}
#4 Una mejor manera: La lista generica trae un metodo ya incluido que nos sirve para borrar multiples elementos
ints2.RemoveAll(delegate(int i) {
return i <4;
});
#5 Pero que pasa si quiero ejecutar una accion en cada elemento que se borre?
ints2.RemoveAll(delegate(int i) {
if (i < 4) {
//*** Perform action here
Console.WriteLine("removing :" + i.ToString());
return true;
}
else
return false;
});
Si el elemento fuera una clase, podrias mandar llamar uno de sus metodos antes de borrarlo (por ejemplo una llamada a la base de datos)
Mas adelante escribire en detalle porque exactamente las alternativas #1 y #2 no funcionan
salu2
No comments:
Post a Comment