замените простой forloop на linq - PullRequest
       13

замените простой forloop на linq

0 голосов
/ 05 декабря 2009

Я хочу знать, как заменить простой цикл foreach на linq. Я не ищу ответы о двух или более циклах .... Это специально для одного цикла foreach ..

List<string> strlist=new List<string>();    
strlist.Add("Hello");
strlist.Add("World");

//The main "to be linq" here...

foreach(string str in strlist)
{
Console.Writeline(str);
}

Теперь, как мне написать этот простой цикл в 1 строку?

Спасибо

Ответы [ 3 ]

6 голосов
/ 05 декабря 2009

Эрик Липперт советует не писать такие циклы как выражения.

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

В этом случае вы циклически повторяете оператор, который имеет побочный эффект для консоли и не возвращает значений. Таким образом, цикл foreach более понятен и разработан специально для этой цели.

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

List<int> numbers = Enumerable.Range(1, 10).ToList();

Отсюда составляем список действий:

List<Action> actions = numbers.Select(n => Console.WriteLine(n)).ToList();

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

foreach (var a in actions)
    a();

И это такой простой шаблон, можно утверждать, что метод расширения RunAll на IEnumerable<Action> не будет плохой вещью. Действительно, в платформу .NET встроена эта концепция: многоадресный делегат - это единственная вещь, которую вы можете вызвать, которая выполняет группу делегатов в списке. В наиболее распространенных случаях использования (событиях) эти делегаты имеют побочные эффекты.

5 голосов
/ 05 декабря 2009

Вы можете использовать метод ForEach :

strlist.ForEach(x => Console.WriteLine(x));

Как указано в комментариях, это работает только для List<T>. Если ваш источник данных IEnumerable<T>, вы можете написать метод расширения:

public static class EnumerableExtensions
{
    public static void ForEach<T>(this IEnumerable<T> inputList, Action<T> action)
    {
        foreach (var item in inputList)
        {
            action(item);
        }
    }
}
3 голосов
/ 05 декабря 2009

Вы можете использовать метод ForEach (либо на List<T>, либо на своем IEnumerable<T>) - но это не очень "идиоматически LINQ-y".

LINQ основан на функциональных принципах, поэтому обычно предоставляемые вами функции не имеют побочных эффектов. ForEach бессмысленно, если функция не имеет побочных эффектов, поэтому оба подхода находятся в напряжении.

Эрик Липперт имеет сообщение в блоге , предоставляющее более подробную информацию.

В принципе нет ничего плохого в использовании foreach, когда вы хотите сделать что-то с данными; LINQ предназначен для запроса данных. Обычно вы создаете запрос LINQ и затем используете оператор foreach, чтобы использовать данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...