2009-06-07 19 views
8

Tengo la siguiente lista genérica que está poblada con una lista de cadena:cómo modificar elementos en una lista genérica utilizando foreach?

List<string> mylist =new List<string>(); 
myList.add("string1"); 
myList.add("string2"); 

decir que quiero añadir 'prueba' al final de cada cadena, ¿cómo puedo hacer de una manera sencilla? Intuitivamente, he intentado esto que compila bien:

myList.ForEach(s => s = s + "test"); 

Pero si luego ver el contenido de la lista, nada ha cambiado. Creo que podría usar un bucle for para recorrer la Lista, pero estoy buscando algo muy simple y usar ForEach se ve muy bien ... pero parece que no funciona. ¿Algunas ideas?

Respuesta

14

El problema es que el Action ha especificado será ejecutado en los elementos de la lista, pero el resultado no se devuelve a ningún lado ... su s es solo una variable local.

Cambio de la lista en contexto probablemente tomará un verdadero foreach, pero si usted está dispuesto a tomar una nueva lista como resultado, usted podría intentar:

list = list.ConvertAll(s => s + "test"); 

No es lo mismo ... pero lo más cerca que puedas ...

+1

Como alternativa IEnumerable .Seleccione (s => s + "prueba") ... –

9

No es posible hacerlo a menos que el tipo de lista sea un tipo de referencia mutable (y en ese caso, aún no puede cambiar la referencia real en la lista, sino el objeto mismo).

La razón es que llama a un delegado Action<T> con la firma:

delegate void Action<T>(T obj); 

y aquí, el argumento es pasado por valor (no es ref). Al igual que cualquier método, no se puede cambiar el argumento de entrada cuando se llama por valor:

El código es esencialmente equivalente a:

void anonymous_method(string s) { 
    s = s + "test"; // no way to change the original `s` inside this method. 
} 

list.ForEach(anonymous_method); 
+0

Gracias por la explicación. Muy útil. – Anthony

+1

También le agradezco la explicación ... Esa es la explicación más simple que he visto ... supera cualquier cosa en MSDN. Ejército de reserva. – corlettk

+0

Sí, me gusta esta respuesta, mucho más limpia e intuitiva – Vincent

Cuestiones relacionadas