2011-12-08 30 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 => ...) –