打破包含switch语句的while循环

71

我在尝试找出如何跳出一个包含switch语句的循环时遇到了问题。break语句只能跳出switch语句,而不能跳出整个循环。

可能有更优雅的解决方案。我已经实现了一个标志(flag),它一开始为true,当被设置为false时结束循环。你能提供更好的解决方案吗?

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

这是需要改进的C#示例:


```csharp while (true) { switch (action) { case "D": done = true; break;
case "Q": quit = true; break;
// Code to handle other cases...
default: break; }
if (done || quit) { break; } } ```
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

谢谢。


8
对我来说,这看起来不错,flag变量是检查循环条件的标准方式。 - Ron Warholic
在Java(以及其他一些语言)中,给循环加上标签并使用带标签的break将是最直接的答案。 - Roy Tinker
15个回答

1
把它封装成一个函数并使用返回语句退出。这个怎么样?

1

写一些类似这样的内容:

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

这个break语句不会与任何情况相关联,它将属于while循环。

0

另一个(不太好的)选择是独特地处理必须立即使用if跳出循环并将其移出switch块的case。如果switch-case非常长,则不是非常优雅:

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");

如果以某种原因将整个事物重新设计为一个新方法(这是最优雅的解决方案),不可接受,则可以在现有方法内部依靠匿名委托执行相同操作。


0
你可以将 switch 语句改为 for/foreach 循环。一旦条件满足,将 "keepOnLooping" 设置为 false,然后使用 break 退出循环。其余部分应该自动处理。

转换到for/foreach?你的意思是别的吧。 - nawfal

-2

可能会起作用,也可能不会,但为什么不试一试呢,只是为了好玩。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接