Как изменить элементы в общем списке с помощью foreach? - PullRequest
8 голосов
/ 07 июня 2009

У меня есть следующий Общий список, который заполнен списком строк:

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

Скажем, я хочу добавить 'test' в конце каждой строки, как я могу сделать это простым способом? Интуитивно я попробовал это, которое компилируется нормально:

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

Но если я тогда посмотрю на содержание Списка, ничего не изменилось. Я думаю, я мог бы использовать цикл for для итерации по списку, но я ищу что-то очень простое и использование ForEach выглядит очень аккуратно .... но, похоже, не работает Есть идеи?

Ответы [ 2 ]

14 голосов
/ 07 июня 2009

Проблема в том, что указанный вами Action выполняется для элементов списка, но результат никуда не возвращается ... ваш s является только локальной переменной.

Изменение списка на месте, вероятно, потребует фактического foreach, но если в результате вы получите новый список, вы можете попробовать:

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

Не совсем то же самое ... но так близко, как вы получите ...

9 голосов
/ 07 июня 2009

Это невозможно сделать, если тип списка не является изменяемым ссылочным типом (и в этом случае вы все равно не можете изменить фактическую ссылку в списке, кроме самого объекта).

Причина в том, что List<T>.ForEach вызывает делегата Action<T> с подписью:

delegate void Action<T>(T obj);

и здесь аргумент передается значением (это не ref). Как и любой метод, вы не можете изменить входной аргумент, когда он вызывается по значению:

Код по существу эквивалентен:

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

list.ForEach(anonymous_method);
...