Anthony
Anthony

Reputation: 7300

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?

Upvotes: 8

Views: 7597

Answers (2)

jerryjvl
jerryjvl

Reputation: 20121

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...

Upvotes: 15

Mehrdad Afshari
Mehrdad Afshari

Reputation: 421978

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);

Upvotes: 9

Related Questions