Как преобразовать все строки в List <string> в нижний регистр с помощью LINQ?

Вчера я увидел фрагмент кода в одном из ответов здесь, на StackOverflow, который заинтриговал меня. Это было примерно так:

 List<string> myList = new List<string> {"aBc", "HELLO", "GoodBye"};

 myList.ForEach(d=>d.ToLower());

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

Итак, мой вопрос заключается в том, есть ли способ, используя выражения LINQ и Lambda, чтобы легко перебирать и изменять содержимое списка аналогично этому.

Спасибо, Макс

Ответ 1

Самый простой подход:

myList = myList.ConvertAll(d => d.ToLower());

Не слишком сильно отличается от кода вашего примера. ForEach завершает исходный список, тогда как ConvertAll создает новый, который необходимо переназначить.

Ответ 2

Это потому, что ToLower возвращает строчную строку вместо преобразования исходной строки. Поэтому вам нужно что-то вроде этого:

List<string> lowerCase = myList.Select(x => x.ToLower()).ToList();

Ответ 3

[TestMethod]
public void LinqStringTest()
{
    List<string> myList = new List<string> { "aBc", "HELLO", "GoodBye" };
    myList = (from s in myList select s.ToLower()).ToList();
    Assert.AreEqual(myList[0], "abc");
    Assert.AreEqual(myList[1], "hello");
    Assert.AreEqual(myList[2], "goodbye");
}

Ответ 4

ForEach использует Action<T>, что означает, что вы можете повлиять на x, если это не было неизменным. Поскольку x является string, он неизменен, поэтому вы ничего не делаете с ним в лямбде, измените его свойства. Решение Kyralessa - ваш лучший вариант, если вы не захотите реализовать свой собственный метод расширения, который позволяет вернуть значение замены.

Ответ 5

var _reps = new List(); // with variant data

_reps.ConvertAll<string>(new Converter<string,string>(delegate(string str){str = str.ToLower(); return str;})).Contains("invisible"))