[英]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.