簡體   English   中英

跳出包含 switch 語句的 while 循環

[英]Break out of a while loop that contains a switch statement

我無法弄清楚如何跳出包含 switch 語句的循環。 Break 是跳出開關,而不是循環。

可能有一個更優雅的解決方案。 我已經實現了一個標志,它開始為真,然后設置為假並結束循環。 你能提供更好的解決方案嗎?

背景:此代碼用於條碼工作流系統。 我們有內置條形碼掃描器的 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

謝謝,

我會盡量避免它,但你可以使用...

轉到

然而,如果你選擇這樣做,拿着干草叉的憤怒暴徒會成為一種職業危害。

我發現這個表格更具可讀性:

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; 
    } 
}

這里的一種選擇是將此循環重構為一個方法(“提取方法”),並使用return

我所知道的唯一其他方法是可怕的 goto。MSDN 也這么說。

但是,我看不出您在這種情況下為什么要使用它。 您實施的方式工作正常,並且比 goto 更易於維護。 我會保留你所擁有的。

您必須使用 goto 語句進行多級中斷。 它似乎是 C# 中唯一的“干凈”方式。 使用標志也很有用,但如果循環有其他運行困境,則需要額外的代碼。

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

有趣的是,其他一些非 c 語言通過執行break levels ;具有多級中斷break levels ; (不過,Java 也同樣沒用,因為它使用偽裝成 continue 的 goto.. :P)

為什么不將開關包裝到一個返回布爾值的方法中以繼續循環? 它的附帶好處是使代碼更具可讀性。 有人寫了一篇論文說我們畢竟不需要 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;
}

你不能輕易跳出外循環,但你可以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");

標志是執行此操作的標准方法。 我所知道的唯一另一種方法是使用goto

您可以用if/else語句替換switch語句。 不需要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)

寫一些類似的東西:

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

此中斷不會與任何情況相關聯。 它將屬於while循環。

IMO,這似乎是打破while循環的完美方式。 它可以滿足您的預期而沒有副作用。 我可以想到做

if(!keepOnLooping)
  break;

但這在執行方面並沒有什么不同。

將其包裝成一個函數並使用 return 語句退出。 怎么樣?

另一個(沒有那么大)替代方案是唯一處理的case ,你必須有一個“循環打出來” if馬上和其移出的switch塊。 如果 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");

此外,如果由於某種原因將整個事物重構為一個新方法(這是對此最優雅的解決方案)是不可接受的,那么您也可以依靠匿名委托在現有方法中執行相同的操作。

您可以將 switch 語句更改為 for/foreach 循環。 一旦滿足條件,將“keepOnLooping”設置為 false,然后使用 break 退出循環。 其余的應該照顧好自己。

可能會或可能不會起作用,但是 lamda 為什么不只是為了好玩而試一試

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM