Строковые значения ForEach to Trim в массиве строк

Мне просто интересно, почему этот ForEach не работает и оставляет значения с завершающим пробелом.

string days = "Monday, Tuesday, Wednesday, Thursday, Friday";

string[] m_days = days.Split(',');

m_days.ToList().ForEach(d => { d = d.Trim(); } );

Я знаю, что есть другие способы сделать это, поэтому мне не нужно и отвечать там.

Ответ 1

Потому что вы не переназначаете обрезанные строки.

var list = m_days.Split(',').Select(s => s.Trim()).ToList();

Почему ForEach не работает или я неправильно использую ForEach?

ForEach не является Linq, это метод List<T>. То, что вы делаете, в основном таково:

foreach(string day in m_days)
{
    day.Trim();  // you are throwing away the new string
}

Ответ 2

Вам нужно назначить вывод вашего ForEach новой переменной, например:

var trimmedResult = m_days.Select(d => d.Trim()).ToList();

Ответ 3

Потому что String.Trim() не изменять исходную строку. Когда вы вызываете ForEach(d => d.Trim()), вы создаете новую обрезанную строку в памяти для каждого элемента списка, но эта строка не назначается нигде. Это то, что вы делаете:

foreach(string d in list)
{
    d.Trim();
}

Вам нужно

m_days = days.Split(',').Select(d => d.Trim()).ToArray();

Ответ 4

string.Trim возвращает новый экземпляр строки. Поэтому вам нужно как-то использовать этот новый экземпляр. Вы не делаете этого в своем коде.
Кроме того, это невозможно при ForEach. На первый взгляд может работать следующее:

m_days.ToList().ForEach(d => { d = d.Trim(); });

Но это вам тоже не поможет, потому что d не передается по ссылке, поэтому вы меняете только локальный параметр, который был передан в ваш делегат, а не экземпляр, хранящийся в списке.

Вы, скорее всего, захотите этого:

var result = days.Split(',').Select(x => x.Trim()).ToList();

Альтернативный способ без LINQ будет выглядеть следующим образом:

var split = days.Split(',');
for(int i = 0; i < split.Length; ++i)
    split[i] = split[i].Trim();