70

在这个代码示例中,有没有办法从 catch 块继续外循环?

while
{
   // outer loop

   while
   {
       // inner loop
       try
       {
           throw;
       }
       catch 
       {
           // how do I continue on the outer loop from here?
           continue;
       }
   }
}
4

10 回答 10

118

更新:这个问题是我关于这个主题的文章的灵感。谢谢你的好问题!


“继续”和“中断”只不过是“goto”的一种令人愉快的语法。显然,通过给它们取可爱的名字并将它们的使用限制在特定的控制结构中,它们不再引起“所有 goto 都是坏的”人群的愤怒。

如果您要做的是继续到外部,您可以简单地在外部循环的顶部定义一个标签,然后“转到”该标签。如果您觉得这样做不会妨碍代码的可理解性,那么这可能是最方便的解决方案。

但是,我会借此机会考虑您的控制流是否会从重构中受益。每当我在嵌套循环中有条件“中断”和“继续”时,我都会考虑重构。

考虑:

successfulCandidate = null;
foreach(var candidate in candidates)
{
  foreach(var criterion in criteria)
  {
    if (!candidate.Meets(criterion))
    {  // TODO: no point in continuing checking criteria.
       // TODO: Somehow "continue" outer loop to check next candidate
    }
  }
  successfulCandidate = candidate;
  break;
}
if (successfulCandidate != null) // do something

两种重构技术:

首先,将内部循环提取到一个方法中:

foreach(var candidate in candidates)
{
  if (MeetsCriteria(candidate, criteria))
  { 
      successfulCandidate = candidate;
      break;
  }
}

第二,可以消除所有的循环吗?如果您因为尝试搜索某些内容而循环,则将其重构为查询。

var results = from candidate in candidates 
              where criteria.All(criterion=>candidate.Meets(criterion))
              select candidate;
var successfulCandidate = results.FirstOrDefault();
if (successfulCandidate != null)
{
  do something with the candidate
}

如果没有循环,则无需中断或继续!

于 2009-07-15T19:40:02.057 回答
40
    while
    {
       // outer loop

       while
       {
           // inner loop
           try
           {
               throw;
           }
           catch 
           {
               // how do I continue on the outer loop from here?
               goto REPEAT;
           }
       }
       // end of outer loop
REPEAT: 
       // some statement or ; 
    }

问题解决了。(什么??为什么你们都给我那种肮脏的眼神?)

于 2009-07-15T19:43:49.210 回答
23

你可以使用休息;陈述。

while
{
   while
   {
       try
       {
           throw;
       }
       catch 
       {
           break;
       }
   }
}

Continue 用于跳回到当前循环的顶部。

如果你需要突破更多的关卡,你要么必须添加某种“if”,要么使用可怕/不推荐的“goto”。

于 2009-07-15T19:23:26.287 回答
9

用内部 while 循环交换 try/catch 结构:

while {
  try {
    while {
      throw;
    }
  }
  catch {
    continue;
  }
}
于 2009-07-15T19:22:00.237 回答
5


,我建议将内部循环提取到单独的方法中。

while
{
   // outer loop
       try
       {
           myMethodWithWhileLoopThatThrowsException()
       }
       catch 
       {
           // how do I continue on the outer loop from here?
           continue;
       }
   }
}
于 2009-07-15T19:23:13.430 回答
3

break在内循环中使用。

于 2009-07-15T19:23:37.080 回答
0

你只想打破会延续外部的内部。

while
{
   // outer loop

   while
   {
       // inner loop
       try
       {
           throw;
       }
       catch 
       {
           // how do I continue on the outer loop from here?
           break;
       }
   }
}
于 2009-07-15T19:24:17.033 回答
0
using System;

namespace Examples
{

    public class Continue : Exception { }
    public class Break : Exception { }

    public class NestedLoop
    {
        static public void ContinueOnParentLoopLevel()
        {
            while(true)
            try {
               // outer loop

               while(true)
               {
                   // inner loop

                   try
                   {
                       throw new Exception("Bali mu mamata");
                   }
                   catch (Exception)
                   {
                       // how do I continue on the outer loop from here?

                       throw new Continue();
                   }
               }
            } catch (Continue) {
                   continue;
            }
        } 
    }

}

}
于 2009-07-23T15:37:08.233 回答
-1

我认为实现这一点的最佳方法是使用break语句。Break结束当前循环从它结束的地方继续执行。在这种情况下,它将结束内部循环跳回外部 while 循环。这就是您的代码的样子:

while
{
   // outer loop

   while
   {
       // inner loop
       try
       {
           throw;
       }
       catch 
       {
           // break jumps to outer loop, ends inner loop immediately.
           break; //THIS IS THE BREAK
       }
   }
}

我相信这就是你想要完成的,对吗?谢谢!

于 2009-07-15T19:35:32.610 回答
-3

使用自己的异常类型,例如 MyException。然后:

while
{
   try {
   // outer loop
   while
   {
       // inner loop
       try
       {
           throw;
       }
       catch 
       {
           // how do I continue on the outer loop from here?
           throw MyException;
       }
   }
   } catch(MyException)
   { ; }
}

这将适用于继续和打破几个级别的嵌套 while 语句。抱歉格式错误;)

于 2009-07-15T19:41:41.850 回答