2.24.2011

Recorriendo una Lista con el ForEach pero sin un for each en C#

Cada vez que utilizamos listas en nuestras aplicaciones existe una altísima probabilidad de tengamos que recorrer la lista para llevar a cabo una acción específica sobre cada uno de los elementos contenidos en la misma. Esta acción se realiza normalmente utilizando la estructura for each o un for tradicional estilo “C++”. Sin embargo; en .NET las listas tienen otra forma de recorrer todos sus elementos y es utilizando el método Lista.ForEach( accion ). Este método me permite definir un delegate genérico para el método y asignarlo como acción, con lo cual cada elemento contenido en la lista es enviado como parámetro al delegate y se ejecuta el método; en otras palabras, el método se ejecuta una vez por cada elemento en la lista.

Ejemplo

Como siempre, para acompañar la teoría vamos a agregar un ejemplo. Supongamos que tenemos una lista de personas y otra lista de personas aprobadas; además, la lista de personas aprobadas solo se puede llenar con las personas que sean mayores de 18 años. Para esto primero vamos a crear una clase persona.

Code Snippet
  1. public class Persona
  2. {
  3.     public int Id { get; set; }
  4.     public string Nombre { get; set; }
  5.     public int Edad { get; set; }
  6. }

El siguiente paso es crear dos variables a nivel de clase – estáticas para no agrandar demasiado el ejemplo – y pertenecientes a la clase program.

Code Snippet
  1. class Program
  2.   {
  3.       static List<Persona> _solicitantes = new List<Persona>();
  4.       static List<Persona> _aprobados = new List<Persona>();

Luego procedemos a agregar unas cuantas personas a la lista de solicitantes.

Code Snippet
  1. static void Main(string[] args)
  2.       {
  3.          
  4.  
  5.           Persona p0 = new Persona
  6.           {
  7.               Id = 1,
  8.               Nombre = "Estela",
  9.               Edad = 18
  10.           };
  11.  
  12.           Persona p1 = new Persona {
  13.               Id = 2,
  14.               Nombre = "Luis",
  15.               Edad = 25
  16.           };
  17.  
  18.           Persona p2 = new Persona
  19.           {
  20.               Id = 3,
  21.               Nombre = "Erick",
  22.               Edad = 17
  23.           };
  24.  
  25.           Persona p3 = new Persona
  26.           {
  27.               Id = 4,
  28.               Nombre = "Carlos",
  29.               Edad = 35
  30.           };
  31.  
  32.           Persona p4 = new Persona
  33.           {
  34.               Id = 5,
  35.               Nombre = "Ana",
  36.               Edad = 16
  37.           };
  38.  
  39.           _solicitantes.Add(p0);
  40.           _solicitantes.Add(p1);
  41.           _solicitantes.Add(p2);
  42.           _solicitantes.Add(p3);
  43.           _solicitantes.Add(p4);

Como podemos ver, ahora tenemos un par de personas que no tienen los 18 años. Ahora vamos a proceder a recorrer la lista y verificar cual persona es mayor de 18 años para agregarla a lista de aprobados, para esto primero tenemos que crear el delegate que hará el procesamiento.

Code Snippet
  1. private static void ProcesarSolicitante(Persona pActual)
  2. {
  3.     if (pActual.Edad > 17)
  4.     {
  5.         _aprobados.Add(pActual);   
  6.     }
  7. }

Ahora, para imprimir la lista, también voy a utilizar un delegate, tal y como se presenta en el siguiente “code snippet”.

Code Snippet
  1. private static void ImprimirPersona(Persona pActual)
  2.         {
  3.             Console.WriteLine("Id: {0}\nNombre: {1},\nEdad: {2}",
  4.                 pActual.Id.ToString(), pActual.Nombre, pActual.Edad.ToString());
  5.         }

Ahora en el método Main, después de agregar la última persona procedemos a invocar el método ForEach de la lista de solicitantes y le asignamos el delegate ProcesarSolicitante.

Code Snippet
  1. _solicitantes.ForEach(ProcesarSolicitante);

Luego de esto procedemos a imprimir la lista de aprobados.

Code Snippet
  1. Console.WriteLine("Usuarios Aceptados");
  2.             Console.WriteLine("------------------");
  3.  
  4.             _aprobados.ForEach(ImprimirPersona);

Al ejecutar el código, podemos ver que en la lista de aprobados solamente aparecen las personas mayores de 17 años.

image

Etiquetas de Technorati: ,,

5 comentarios:

JPCP dijo...

Amigo, muy buen post.
Pero tengo una duda: ¿en vez de utilizar un delegate, no se puede usar Lambda?

Diego Rojas dijo...

Hola JPCP. Gracias por el comentario. Si, de hecho hace un tiempo atrás hice un post para sustituir un delegate por una expresión Lambda. Aqui esta el link :)
http://icomparable.blogspot.com/2009/10/expresiones-lambda-en-vbnet-90.html

Ele dijo...

Con esto podes modificar la cantidad de items dentro de la lista y seguir recorriendola?
Porque estoy teniendo problemas con mi codigo y la exception dice "Colección modificada; puede que no se ejecute la operación de enumeración."

Anónimo dijo...

Como seria el codigo de este ejemplo en c# usando una expresion lambda?

Anónimo dijo...

no me sirvio de nada busca como recorrer una lista :/