Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to modify items in a Generic List using foreach?

I have the following Generic List which is populated with a list of string:

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

Say I want to add 'test' at the end of each string, how can I do it in a simple way? Intuitively, I tried this which compiles ok:

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

But if I then look at the content of the List, nothing has changed. I guess I could use a for loop to iterate through the List but I'm looking for something very simple and using ForEach looks very neat.... but doesn't seem to work. Any ideas?

like image 625
Anthony Avatar asked Jun 07 '09 11:06

Anthony


2 Answers

The problem is that the Action you specified gets executed on the elements of the list, but the result is not put back anywhere... your s is a local variable only.

Changing the list in-place will probably take an actual foreach, but if you are happy to take a new list as the result, you could try:

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

Not quite the same... but as close as you'll get...

like image 188
jerryjvl Avatar answered Oct 11 '22 22:10

jerryjvl


It's not possible to do that unless the list type is a mutable reference type (and in that case, you can't still change the actual reference in the list but the object itself).

The reason is that List<T>.ForEach calls a Action<T> delegate with signature:

delegate void Action<T>(T obj);

and here, the argument is passed by value (it's not ref). Like any method, you can't change the input argument when it's called by value:

The code is essentially equivalent to:

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

list.ForEach(anonymous_method);
like image 38
mmx Avatar answered Oct 11 '22 22:10

mmx