快速提问,请参阅此代码:
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(value)没有被执行?
然而,这还没有执行,另一个有问题的方法是使用扩展方法对 IEnumerable 进行 foreach ?
除此之外:IEnumerable.ToList().Foreach(p=>...)
答案 0 :(得分:17)
为什么result.Add(value)没有被执行?
这是因为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进行预测吗?
您可以编写自己的扩展方法:
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。
答案 1 :(得分:3)
Select是延迟的,执行会延迟,直到您开始枚举结果为止。您需要通过调用.ToArray或通过循环结果来使用结果集:
list.Select(value =>
{
result.Add(value);//Does not work??
return value;
}).ToArray();
答案 2 :(得分:-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添加到结果中。测试一下。我刚刚做了。