C# 跳出嵌套循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/324831/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 23:15:09  来源:igfitidea点击:

Breaking out of a nested loop

c#for-loopnested-loops

提问by GurdeepS

If I have a for loop which is nested within another, how can I efficiently come out of both loops (inner and outer) in the quickest possible way?

如果我有一个嵌套在另一个循环中的 for 循环,我怎样才能以最快的方式有效地从两个循环(内部和外部)中出来?

I don't want to have to use a boolean and then have to say go to another method, but rather just to execute the first line of code after the outer loop.

我不想必须使用布尔值然后不得不说转到另一个方法,而只是在外循环之后执行第一行代码。

What is a quick and nice way of going about this?

有什么快速而好的方法来解决这个问题?

I was thinking that exceptions aren't cheap/should only be thrown in a truly exceptional condition etc. Hence I don't think this solution would be good from a performance perspective.

我在想异常并不便宜/应该只在真正异常的情况下抛出等等。因此,从性能的角度来看,我认为这个解决方案不是很好。

I don't feel it it is right to take advantage of the newer features in .NET (anon methods) to do something which is pretty fundamental.

我认为利用 .NET 中的新功能(匿名方法)来做一些非常基本的事情是不对的。

采纳答案by Marc Gravell

Well, goto, but that is ugly, and not always possible. You can also place the loops into a method (or an anon-method) and use returnto exit back to the main code.

嗯,goto但那很丑陋,而且并不总是可能的。您还可以将循环放入一个方法(或一个匿名方法)中,并用于return退出回到主代码。

    // goto
    for (int i = 0; i < 100; i++)
    {
        for (int j = 0; j < 100; j++)
        {
            goto Foo; // yeuck!
        }
    }
Foo:
    Console.WriteLine("Hi");

vs:

对比:

// anon-method
Action work = delegate
{
    for (int x = 0; x < 100; x++)
    {
        for (int y = 0; y < 100; y++)
        {
            return; // exits anon-method
        }
    }
};
work(); // execute anon-method
Console.WriteLine("Hi");


Note that in C# 7 we should get "local functions", which (syntax tbd etc) means it should work something like:

请注意,在 C# 7 中,我们应该获得“本地函数”,这(语法 tbd 等)意味着它应该像这样工作:

// local function (declared **inside** another method)
void Work()
{
    for (int x = 0; x < 100; x++)
    {
        for (int y = 0; y < 100; y++)
        {
            return; // exits local function
        }
    }
};
Work(); // execute local function
Console.WriteLine("Hi");

回答by Thomas Hansen

I think unless you want to do the "boolean thing" the only solution is actually to throw. Which you obviously shouldn't do..!

我认为除非你想做“布尔值的事情”,否则唯一的解决办法就是扔。你显然不应该这样做..!

回答by NoizWaves

Is it possible to refactor the nested for loop into a private method? That way you could simply 'return' out of the method to exit the loop.

是否可以将嵌套的 for 循环重构为私有方法?这样你就可以简单地从方法中“返回”以退出循环。

回答by David Rodríguez - dribeas

Don't quote me on this, but you could use gotoas suggested in the MSDN. There are other solutions, as including a flag that is checked in each iteration of both loops. Finally you could use an exception as a really heavyweight solution to your problem.

不要引用我的话,但是您可以按照 MSDN 中的建议使用goto。还有其他解决方案,包括在两个循环的每次迭代中检查的标志。最后,您可以使用异常作为解决问题的重量级解决方案。

GOTO:

去:

for ( int i = 0; i < 10; ++i ) {
   for ( int j = 0; j < 10; ++j ) {
      // code
      if ( break_condition ) goto End;
      // more code
   }
}
End: ;

Condition:

健康)状况:

bool exit = false;
for ( int i = 0; i < 10 && !exit; ++i ) {
   for ( int j = 0; j < 10 && !exit; ++j ) {
      // code
      if ( break_condition ) {
         exit = true;
         break; // or continue
      }
      // more code
   }
}

Exception:

例外:

try {
    for ( int i = 0; i < 10 && !exit; ++i ) {
       for ( int j = 0; j < 10 && !exit; ++j ) {
          // code
          if ( break_condition ) {
             throw new Exception()
          }
          // more code
       }
    }
catch ( Exception e ) {}

回答by tvanfosson

Use a suitable guard in the outer loop. Set the guard in the inner loop before you break.

在外环中使用合适的防护装置。在你打破之前,在内环中设置防护装置。

bool exitedInner = false;

for (int i = 0; i < N && !exitedInner; ++i) {

    .... some outer loop stuff

    for (int j = 0; j < M; ++j) {

        if (sometest) {
            exitedInner = true;
            break;
        }
    }
    if (!exitedInner) {
       ... more outer loop stuff
    }
}

Or better yet, abstract the inner loop into a method and exit the outer loop when it returns false.

或者更好的是,将内部循环抽象为一个方法,并在它返回 false 时退出外部循环。

for (int i = 0; i < N; ++i) {

    .... some outer loop stuff

    if (!doInner(i, N, M)) {
       break;
    }

    ... more outer loop stuff
}

回答by Dustin Getz

factor into a function/method and use early return, or rearrange your loops into a while-clause. goto/exceptions/whatever are certainly not appropriate here.

分解为函数/方法并使用提前返回,或将循环重新排列为 while 子句。goto/exceptions/whatever在这里肯定不合适。

def do_until_equal():
  foreach a:
    foreach b:
      if a==b: return

回答by Windows programmer

You asked for a combination of quick, nice, no use of a boolean, no use of goto, and C#. You've ruled out all possible ways of doing what you want.

您要求快速、漂亮、不使用布尔值、不使用 goto 和 C# 的组合。你已经排除了做你想做的所有可能的方式。

The most quick and least ugly way is to use a goto.

最快速和最不丑陋的方法是使用 goto。

回答by Nils Pipenbrinck

C# adaptation of approach often used in C - set value of outer loop's variable outside of loop conditions (i.e. for loop using int variable INT_MAX -1is often good choice):

C# 中经常使用的方法的 C# 改编 - 在循环条件之外设置外循环变量的值(即使用 int 变量的 for 循环INT_MAX -1通常是不错的选择):

for (int i = 0; i < 100; i++)
{
    for (int j = 0; j < 100; j++)
    {
        if (exit_condition)
        {
            // cause the outer loop to break:
            // use i = INT_MAX - 1; otherwise i++ == INT_MIN < 100 and loop will continue 
            i = int.MaxValue - 1;
            Console.WriteLine("Hi");
            // break the inner loop
            break;
        }
    }
    // if you have code in outer loop it will execute after break from inner loop    
}

As note in code says breakwill not magically jump to next iteration of the outer loop - so if you have code outside of inner loop this approach requires more checks. Consider other solutions in such case.

正如代码中的注释所说,break不会神奇地跳到外循环的下一次迭代——所以如果你有内循环之外的代码,这种方法需要更多的检查。在这种情况下考虑其他解决方案。

This approach works with forand whileloops but does not work for foreach. In case of foreachyou won't have code access to the hidden enumerator so you can't change it (and even if you could IEnumeratordoesn't have some "MoveToEnd" method).

这种方法适用于forwhile循环,但不适用于foreach. 如果foreach您没有对隐藏枚举器的代码访问权限,因此您无法更改它(即使您可以IEnumerator没有一些“MoveToEnd”方法)。

Acknowledgments to inlined comments' authors:
i = INT_MAX - 1suggestion by Meta
for/foreachcomment by ygoe.
Proper IntMaxby jmbpiano
remark about code after inner loop by blizpasta

对内联评论作者的致谢: Meta 的
i = INT_MAX - 1建议/ ygoe 的评论。 正确的jmbpiano通过内部循环后约代码备注blizpasta
forforeach
IntMax

回答by Jesse C. Slicer

Since I first saw breakin C a couple of decades back, this problem has vexed me. I was hoping some language enhancement would have an extension to break which would work thus:

自从break几十年前我第一次看到C以来,这个问题一直困扰着我。我希望某些语言增强功能可以扩展到 break 从而可以工作:

break; // our trusty friend, breaks out of current looping construct.
break 2; // breaks out of the current and it's parent looping construct.
break 3; // breaks out of 3 looping constructs.
break all; // totally decimates any looping constructs in force.

回答by dviljoen

I've seen a lot of examples that use "break" but none that use "continue".

我见过很多使用“break”但没有使用“continue”的例子。

It still would require a flag of some sort in the inner loop:

它仍然需要在内循环中使用某种标志:

while( some_condition )
{
    // outer loop stuff
    ...

    bool get_out = false;
    for(...)
    {
        // inner loop stuff
        ...

        get_out = true;
        break;
    }

    if( get_out )
    {
        some_condition=false;
        continue;
    }

    // more out loop stuff
    ...

}