2011-12-08 76 views
5

快速的問題擴展方法,請參見下面的代碼:的foreach與IEnumerable的

List<int> result = new List<int>(); 

var list = new List<int> { 1, 2, 3, 4 }; 

list.Select(value => 
    { 
     result.Add(value);//Does not work?? 
     return value; 
    }); 

和:

result.Count == 0 //true 

爲什麼result.Add(值)不執行?

然而,這不執行,另一個問題是有辦法做的foreach的IEnumerableExtention法

除了這種方式:IEnumerable.ToList().Foreach(p=>...)

+0

你需要作出委託 – MethodMan

+1

@DJKRAZE它已經是一個委託。 –

+0

我在下面發佈了我的代表示例以便利用list.ForEach – MethodMan

回答

17

爲什麼result.Add(值)不執行?

這是因爲LINQ使用延遲執行。在您實際枚舉結果(Select的返回)之前,代表不會執行。

爲了演示,請嘗試以下操作:

List<int> result = new List<int>(); 

var list = new List<int> { 1, 2, 3, 4 }; 

var results = list.Select(value => 
    { 
     result.Add(value);//Does not work?? 
     return value; 
    }); 

foreach(var item in results) 
{ 
    // Just iterating through this will cause the above to execute... 
} 

話雖這麼說,這是一個壞主意。如果可以避免,LINQ查詢不應該有副作用。將Select想象爲轉換數據的方式,而不是執行代碼。

但是,這並沒有執行,另一個問題是有辦法做一個IEnumerable與foreach方法foreach?

你可以編寫自己的擴展方法:

public static void ForEach<T>(this IEnumerable<T> items, Action<T> action) 
{ 
    foreach(var item in items) 
     action(item); 
} 

不過,我建議不這樣做。有關詳細信息,請參閱Eric Lippert's post on the subject

+0

感謝您的回答,您的描述解決了我的問題理解IEnumerable和延遲執行混淆。 –

3

選擇是懶惰的,並且延遲執行直到您開始枚舉結果。你需要通過調用.ToArray例如或者通過遍歷結果消耗的結果集:

list.Select(value => 
    { 
     result.Add(value);//Does not work?? 
     return value; 
    }).ToArray(); 
+0

如果我打算使用一個方法來強制枚舉,我會使用像Max()這樣的常量內存,而不是ToArray()。 –

-1
List<int> result = new List<int>(); 
var list = new List<int> { 1, 2, 3, 4 }; 
list.ForEach(delegate(int sValue) 
{ 
    result.Add(sValue); 
}); 

這工作,但所有,並增加了1 2 3 4成的結果。測試一下。我已經做了。

+0

我提到過:除了這種方式:IEnumerable.ToList()。Foreach(p => ...) –