【问题标题】:How to perform a double loop jump?如何进行双循环跳跃?
【发布时间】:2013-05-26 16:56:28
【问题描述】:

我有这样的代码:

while(condition)
{
    foreach(string s in list)
    {
        switch(j)
        {
            case 1:
            //do something
            continue;//can I break out of foreach here?
            case 2:
            //do another
            continue;//break 
            ..other cases;
        }
        //do some stuff
    }
    //do some stuff
}

我正在考虑goto,但我听说过很多关于它的坏消息。

【问题讨论】:

  • 请在您的问题中添加相关语言标签...
  • 您可以设置flag,如果设置了flag,则中断。从而避免 goto....但是 "a wholesale ban (on goto) is just silly" -- @Jon Purdy stackoverflow.com/a/16555996/436084
  • 你不应该为每个人打破一个。使用 while 和迭代器进行循环,并使用标志作为第二个条件。
  • 如果你把整个东西放在一个函数中,你可以在任何你想中断的地方放一个 return 语句。
  • 奥利说什么。例如,在 C++ 和 Perl 中,答案会非常不同。

标签: c# loops foreach switch-statement


【解决方案1】:

我假设您尝试做的是从开关内部中断,并让它退出 for 循环而不是 while 循环。我的建议是将整个事情放入一个函数中,并在您想要中断的任何地方放置一个 return 语句。例如:

void f () {
        foreach(string s in list) {
            switch(j) {
                case 1:
                //do something
                return; 
                case 2:
                //do another
                continue;//break 
                ..other cases;
             }
         //do some stuff
        }
}

// ... later somewhere
while (condition) {
    f();
}

【讨论】:

  • 在现代,人们对​​可读代码的偏好明显高于微优化。在 99.9% 的情况下,函数调用足够快。
  • 是的,但是在某些情况下过多的堆栈展开可能会很昂贵。但是您的解决方案 def 有效,没有错:)
  • 在某些情况下,C# 编译器可以决定使函数内联,这将使性能问题变得毫无意义。你最好写出最干净、最易读的代码,让编译器负责微优化。
【解决方案2】:

只需使用布尔变量:

while(condition)
{
    foreach(string s in list)
    {
        var breakout = false;
        switch(j)
        {
            case 1:
                //do something
                breakout = true;
                break;
            // ...
        }

        if(breakout)
        {
            break;
        }
    }
    //do some stuff
}

【讨论】:

    【解决方案3】:

    布尔状态变量应该可以解决问题:

    bool isBadInput = false;
    bool isRunning = true;
    
    while(isRunning && !isBadInput){
      for(int j = 0; j < list.size() && !isBadInput; ++j){
         switch(j){
           case 0: 
             int res = handleCase0();
             if(res == -1){ 
                isBadInput = true;
                isRunning = false;
             }
             break;
          //similar for other cases
      }
    }
    

    【讨论】:

    • 是的,我想到了一个变量,但我想知道是否有更好的结构特征。
    • 如果结构是你想要的,那么如果可能的话,考虑让这些循环发挥作用。这样更容易阅读和重用
    【解决方案4】:

    我正在考虑goto,但我听说过很多关于它的坏消息。

    那么您应该确保在做出决定之前充分了解情况。从GOTO still considered harmful? 链接的文章深入探讨了这个主题。

    编写您认为简洁地表达您的意图、符合您的编程语言并且最终最容易维护的代码。

    【讨论】:

    • 我认为任何问题都基于this answer
    • ...我的答案(部分)基于this comment 对该答案。 goto 语句有它们的位置(尽管我不记得上次我实际上不得不使用一个语句)。在这种情况下,我可能只使用函数中的return,但这可能并不适用于所有情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多