2009-12-05 47 views
0

我想知道如何用linq替換一個簡單的foreach循環。我不是在尋找大約2個或多圈的答案....這是專門爲一個單一的foreach循環..用linq替換一個簡單的forloop

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(); 

雖然我們正在處理的有副作用的行爲,我們實際上並沒有在運行當中所有,所以對該清單內容的任何進一步操縱都不會產生副作用。後來終於當我們有我們需要的列表,我們可以使用一個for循環來執行它:

foreach (var a in actions) 
    a(); 

而就是這樣一個簡單的模式,它可以說,在IEnumerable<Action>一個擴展方法是什麼壞事。事實上,.NET框架內置了這個概念:多播委託是你可以調用的一個單一的東西,它執行列表上的一堆委託。在最常見的用例(事件)中,這些代表有副作用。

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 一起使用。 – 2009-12-05 08:38:13

+0

是的,但是因爲'IEnumerable '沒有等價物,所以爲此實現擴展方法應該是相當簡單的。 – 2009-12-05 09:14:03

3

可以使用ForEach的方法(上List<T>或您自己的IEnumerable<T>) - 但它不是很「地道LINQ-Y」。

LINQ基於功能原理 - 所以您提供的功能通常預計不會產生副作用。如果功能無副作用,那麼ForEach是沒有意義的,所以這兩種方法都處於緊張狀態。

Eric Lippert有一個blog post提供更多的細節。

基本上使用foreach當你想要東西與數據沒有什麼不對; LINQ是指查詢的數據。通常你建立一個LINQ查詢,然後用foreach聲明使用這個數據。