ForEach():为什么不能在内部使用break / continue

时间:2010-12-14 12:22:11

标签: c# foreach break continue

由于ForEach()方法遍历所有列表成员,为什么不能使用 break / continue 子句,而我可以在普通的foreach循环中使用它们

lstTemp.ForEach(i=>
 {
   if (i == 3)
   break;
   //do sth
 }
);

错误:

  

“没有封闭的循环   打破或继续“

11 个答案:

答案 0 :(得分:19)

因为ForEach是一种方法,而不是常规的foreach循环。 ForEach方法适用于简单任务,如果您需要中断或继续使用常规lstTemp循环迭代foreach

通常,ForEach的实现方式如下:

public static ForEach<T>(this IEnumerable<T> input, Action<T> action)
{
  foreach(var i in input)
    action(i);
}

由于这是一种常规的方法调用,action对封闭的foreach一无所知,因此您无法中断。

答案 1 :(得分:17)

大概是因为你正在使用lambda而lambda的内容对于在循环中使用它的事实一无所知。

答案 2 :(得分:10)

而不是使用中断,首先执行这样的过滤器(它可能不是您需要的精确过滤器,但说明了这一点)

lstTemp.Where(i => i!= 3).ForEach(i=> // do sth);

答案 3 :(得分:6)

return将在continue中充当ForEach

示例:

var list = new List<int>() {1, 2, 3, 4};
list.ForEach(i => 
    {
        if (i == 3)
            return;
        Console.WriteLine(i);
    }
);

打印1,2,4。

3 - 跳过。

答案 4 :(得分:5)

要仅迭代部分项目并完美模拟中断,您可以使用FirstOrDefault

lstTemp.FirstOrDefault(i=>
 {
   if (i == 3)
       return true;

   //do stuff

   return false;
 }
);

对于包含100000个项目的列表,如果第10个项目为3,它将仅迭代10次,使用Where解决方案将起作用,但首先迭代整个列表。

答案 5 :(得分:4)

我解释的方式如下:ForEach方法,而不是语言功能。 C#foreach构造是该语言的一项功能,其中允许使用其他语言构建breakcontinue

我还要指出(不是试图判断,只是做一个观察)这是一个很好的例子,说明为什么一些开发人员反对使用ForEach方法:它并没有真正节省输入这个简单的情况,它需要一个不必要的重定向,并且它无论如何都没有foreach的所有功能。

在我看来,ForEach方法有意义的主要场景是IEnumerable<T>的扩展 - 放在方法调用链的末尾。对我来说,似乎有点奇怪,他们将它添加到List<T>

答案 6 :(得分:2)

break和continue是需要编译器支持的C#语言关键字。 ForEach,对C#编译器来说,只是一种方法。

答案 7 :(得分:1)

因为ForEach是一个方法而不是常规的foreach循环,所以需要在case break中使用常规foreach循环迭代lstTemp,但是如果继续使用在ForEach方法内部返回。

var lstTemp = new List<int>() {1, 2, 3, 4};
lstTemp.ForEach(i=>
{
     if (i == 3) return;
     //do sth
     Console.WriteLine(i);
});

输出:1,2,4

答案 8 :(得分:0)

因为您为列表中的每个项目委派了一个操作。

答案 9 :(得分:0)

您可以编写一个扩展方法“ForEachWhile”,它接受Function<T, bool>并在false时停止。

答案 10 :(得分:-1)

我用过它

        list.ForEach((item) =>
        {
            if( isBreak == false ) do
            {
                if (isContinue)
                    break;

                // TODO
            } while (false); }
        });