【问题标题】:ForEach() : Why can't use break/continue insideForEach() : 为什么不能在里面使用 break/continue
【发布时间】:2011-05-25 06:09:37
【问题描述】:

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

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

错误:

"没有封闭的循环 中断或继续”

【问题讨论】:

标签: c# foreach break continue


【解决方案1】:

因为 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

【讨论】:

    【解决方案2】:

    return 将在ForEach 中充当continue

    例子:

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

    打印 1、2、4。

    3 - 跳过。

    【讨论】:

      【解决方案3】:

      我用过

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

      【讨论】:

      • 这并不能完全回答这个问题。 OP 询问为什么他/她不能像正常循环一样使用中断/继续。
      • 尝试删除do-while 并使用break,哈哈。
      【解决方案4】:

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

      lstTemp.FirstOrDefault(i=>
       {
         if (i == 3)
             return true;
      
         //do stuff
      
         return false;
       }
      );
      

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

      【讨论】:

      • Where 方法不会迭代集合,请参阅:延迟执行。
      • @James 也许 iterate 不是正确的词.. 但是要找到所有匹配的项目,必须以某种方式检查所有项目,不是吗?
      • 阅读 yield 关键字的工作原理,因为这就是 LINQ 查询的工作方式。在这里解释太长了,但是不,不是所有的项目都必须检查;只会检查调用链请求的项目。与您的 FirstOrDefault 完全相同,它将迭代直到匹配。
      【解决方案5】:

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

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

      在我看来,ForEach 方法有意义的主要场景是作为IEnumerable&lt;T&gt; 的扩展——放在方法调用链的末尾。他们将其添加到List&lt;T&gt; 似乎(对我而言)有点奇怪。

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

        • -1 不一样。您的代码将为每个 i != 3 运行。提供的代码将运行到 i == 3。
        • 这似乎是“继续”的最佳方式。此外,我们可以为“break”写“return”。
        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

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

            通常,ForEach 是这样实现的:

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

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

            【讨论】:

            • 既然是方法调用,能不能直接return而不是break?
            • 不,你只会从方法本身返回。你将无法以这种方式突破外部 foreach。
            【解决方案10】:

            大概是因为您使用的是 lambda,而 lambda 的内容不知道它是在循环中使用的。

            【讨论】:

              猜你喜欢
              • 2012-04-07
              • 2015-12-09
              • 1970-01-01
              • 2022-01-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多