23

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

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

错误:

“没有可以中断或继续的封闭循环”

4

10 回答 10

24

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

通常,ForEach是这样实现的:

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

因为它是一个普通的方法调用,action对封闭的一无所知foreach,因此你不能打破。

于 2010-12-14T12:26:38.947 回答
21

return将像continueForEach.

例子:

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

打印 1、2、4。

3 - 跳过。

于 2014-08-28T10:17:50.953 回答
17

大概是因为您使用的是 lambda 并且 lambda 的内容对它在循环中使用的事实一无所知。

于 2010-12-14T12:23:22.737 回答
10

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

lstTemp.Where(i => i!= 3).ForEach(i=> // do sth);
于 2010-12-14T12:35:56.610 回答
5

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

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

   //do stuff

   return false;
 }
);

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

于 2010-12-14T13:42:39.887 回答
5

因为 ForEach 是一种方法,而不是常规的 foreach 循环,所以需要使用常规的 foreach 循环遍历 lstTemp 以防中断,但如果继续在 ForEach 方法内使用 return。

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

输出:1、2、4

于 2015-09-06T04:45:10.373 回答
4

我解释它的方式是这样的:ForEach是一种方法,而不是一种语言特征。C#foreach构造是其他语言构造break并被continue允许使用的语言的特征。

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

在我看来,ForEach方法有意义的主要场景是作为IEnumerable<T>--to 的扩展,放在方法调用链的末尾。他们将其添加到List<T>.

于 2010-12-14T12:28:14.127 回答
2

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

于 2010-12-14T12:27:57.717 回答
0

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

于 2010-12-14T12:28:45.367 回答
-2

我用过

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

                // TODO
            } while (false); }
        });
于 2013-10-24T13:03:35.033 回答