打破包含switch语句的while循环

时间:2009-12-31 22:50:20

标签: c# while-loop break

我无法弄清楚如何突破包含switch语句的循环。中断突破开关,而不是循环。

这可能是一个更优雅的解决方案。我已经实现了一个标志,该标志以true开头并设置为false并结束循环。你能提供更好的解决方案吗?

背景:此代码用于条形码工作流程系统。我们有内置条形码扫描仪的PocketPC。此代码用于其中一个功能。它会在整个例程中提示用户输入不同的数据。这件作品允许他们滚动显示在PocketPC终端上显示该信息的一些库存记录(分页结果),并允许他们输入“D”表示完成,“Q”表示退出。

以下是需要改进的当前C#示例:

do
{
    switch (MLTWatcherTCPIP.Get().ToUpper())
    {
        case "": //scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "P": //scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "D": //DONE (exit out of this Do Loop)
            // break; // this breaks out of the switch, not the loop
            // return; // this exists entire method; not what I'm after
            keepOnLooping = false;
            break;
        case "Q": //QUIT (exit out to main menu)
            return;
        default:
            break;
    }
} while (keepOnLooping);

以下是在VB.NET中执行此操作的代码示例

Do
    Select Case MLTWatcherTCPIP.Get().ToUpper
        Case "" ''#scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown()
        Case "P" ''#scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextUp()
        Case "D" ''#DONE (exit out of this Do Loop)
            Exit Do
        Case "Q" ''#QUIT (exit out to main menu)
            Return
    End Select
Loop

谢谢,

15 个答案:

答案 0 :(得分:43)

我试图避免它,但你可以使用......

goto

然而,如果你选择这样做,那些带干草叉的愤怒小怪会成为职业危害。

答案 1 :(得分:38)

我发现这种形式更具可读性:

bool done = false;
while (!done) 
{ 
    switch (MLTWatcherTCPIP.Get().ToUpper()) 
    { 
        case "": //scroll/display next inventory location 
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); 
            break; 
        case "P": //scroll/display previous inventory location 
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); 
            break; 
        case "D": //DONE (exit out of this Do Loop) 
            done = true;
            break; 
        case "Q": //QUIT (exit out to main menu) 
            return; 
        default: 
            break; 
    } 
}

答案 2 :(得分:29)

此处的一个选项是将此循环重构为方法(“提取方法”),并使用return

答案 3 :(得分:12)

我所知道的另一种方式是可怕的goto。 MSDN also says this.

但是,我认为没有理由在这种情况下使用它。您实现的方式工作正常,并且比goto更易于维护。我会保留你拥有的东西。

答案 4 :(得分:10)

您必须使用goto语句进行多级中断。它似乎是C#中唯一“干净”的方式。使用标志也很有用,但如果循环有其他运行困境,则需要额外的代码。

http://msdn.microsoft.com/en-us/library/aa664756(VS.71).aspx

可能有趣的是,通过执行break levels;,其他一些非c语言有多级别中断(但Java也没用,因为它使用goto伪装成一个继续......:P)

答案 5 :(得分:8)

为什么不将开关包装成一个返回布尔值以保持循环的方法?这样可以使代码更具可读性。有人写论文说我们毕竟不需要goto语句;)

do
{
    bool keepOnLooping = TryToKeepLooping();
} while (keepOnLooping);

private bool TryToKeepLooping()
{
    switch (MLTWatcherTCPIP.Get().ToUpper())
    {
        case "": //scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "P": //scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "D": //DONE (exit out of this Do Loop)
            // break; // this breaks out of the switch, not the loop
            // return; // this exists entire method; not what I'm after
            return false;
        case "Q": //QUIT (exit out to main menu)
            return true;
        default:
            break;
    }

    return true;
}

答案 6 :(得分:4)

标志是执行此操作的标准方法。我所知道的另一种方法是使用goto

答案 7 :(得分:4)

你不能轻易地突破外圈,但你可以continue

如果你颠倒你的逻辑,那么你就明白了。 请注意,在switch语句后面有一个break来退出循环。

在我看来,这不是一个非常易读的代码,我认为旗帜仍然是最好的。

   do
         {
            switch (Console.ReadKey().KeyChar.ToString())
            {
                case "U":
                    Console.WriteLine("Scrolling up");
                    continue;

                case "J":
                    Console.WriteLine("Scrolling down");
                    continue;

                case "D": //DONE (exit out of this Do Loop)
                    break;

                case "Q": //QUIT (exit out to main menu)
                    return;

                default:
                    Console.WriteLine("Continuing");
                    continue;
            }

            break;

        } while (true);

        Console.WriteLine("Exited");

答案 8 :(得分:2)

您可以使用switch语句替换if/else语句。不需要goto并且break语句离开循环:

do
{
  String c = MLTWatcherTCPIP.Get().ToUpper();

  if (c = "")
    MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
  else if (c = "P")
    MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextUp();
  else if (c = "D")
     break;
  else if (c = "Q")
    return;
  else
  {
    // Handle bad input here.
  }
} while (keepLooping)

答案 9 :(得分:1)

IMO,这似乎是打破while循环的完美方式。它做你期望的没有副作用。我想到了

if(!keepOnLooping)
  break;

但这在执行方面并没有什么不同。

答案 10 :(得分:1)

将其包装到函数中并使用return语句退出。怎么样?

答案 11 :(得分:1)

写下类似的内容:

case "Exit/Break" :
                  //Task to do
                    if(true)
                      break;

此中断不会与任何情况相关联。它将属于while循环。

答案 12 :(得分:0)

您可以将switch语句更改为for / foreach循环。满足条件后,将“keepOnLooping”设置为false,然后使用break退出循环。其余的应该照顾好自己。

答案 13 :(得分:0)

另一个(不那么好)替代方案是唯一地处理case,你必须立即用if“突破循环”并将其移出switch阻止。如果开关盒非常长,则不是非常优雅:

do
{
    var expression = MLTWatcherTCPIP.Get().ToUpper();
    if (expression = "D") //DONE (exit out of this Do Loop)
    {   
        statement;
        break;
    }

    switch (expression)
    {
        case "": //scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "P": //scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "Q": //QUIT (exit out to main menu)
            return;
        default:
            break;
    }
} while (true); //or whatever your condition is

你也可以让case本身成为while循环条件的一部分,考虑到你只需要摆脱循环并且表达式本身的计算是微不足道的(比如读取变量)

do
{
    switch (expression)
    {
        case "": //scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "P": //scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "Q": //QUIT (exit out to main menu)
            return;
        default:
            break;
    }
} while (condition && expression != "D");

另外,如果将整个事物重构为一个新方法(这是最优雅的解决方案)由于某种原因是不可接受的,那么你也可以依靠匿名委托在现有方法中做同样的事情。

答案 14 :(得分:-1)

可能或可能不行,但lamda为什么不为了好玩而试一试呢

while(  (expr) => (){
switch(expr){
case 1: dosomething; return true; 
case 2 : something;return true;
case exitloop:return false;}
});