在IEnumerable上使用扩展方法的Foreach

时间:2011-12-08 21:32:51

标签: c# foreach extension-methods 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(value)没有被执行?

然而,这还没有执行,另一个有问题的方法是使用扩展方法 IEnumerable 进行 foreach

除此之外:IEnumerable.ToList().Foreach(p=>...)

3 个答案:

答案 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添加到结果中。测试一下。我刚刚做了。