2009-12-05 2 views
0

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

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 строку?

Благодаря

ответ

6

The advice of Eric Lippert не писать такие циклы, как выражения.

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

В этом случае вы выполняете цикл, чтобы повторить инструкцию, которая имеет побочный эффект на консоли и не возвращает значения. Таким образом, цикл 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 Framework встроена эта концепция: делегат многоадресной рассылки - это одна вещь, которую вы можете назвать, которая выполняет кучу делегатов в списке. В наиболее распространенных случаях использования (событиях) эти делегаты имеют побочные эффекты.

5

Вы можете использовать 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); 
     } 
    } 
} 
+0

Просто указывая, что работает только со списком (что имеет место в заданном вопросе), в то время как материал LINQ обычно работает с IEnumerable . –

+0

Да, но поскольку для IENumerable нет эквивалента '', это должно быть довольно тривиально для реализации метода расширения для этого. –

3

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

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

У Эрика Липперта есть blog post с более подробной информацией.

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

Смежные вопросы