switch文が含まれているwhileループから抜け出します
-
22-09-2019 - |
質問
私は、switch文が含まれているループから抜け出す方法を考え出す問題を抱えています。スイッチではなく、ループの外に休憩を破るます。
これをよりエレガントな解決策は、おそらくあります。私は本当のようにして起動し、falseに設定されますし、ループを終了フラグを実装しています。あなたがよりよい解決策を提供することはできますか?
背景:このコードは、バーコードのワークフローシステムで使用されています。私たちは、内蔵のバーコードスキャナを持っているポケットPCを持っている。このコードは、これらの機能の一つで使用されています。これは、ルーチンを通してデータの異なる部分をユーザーに要求します。この作品は彼らがポケットの端末(ページング結果)にその情報を表示するいくつかのインベントリレコードをスクロールすることを可能にして終了するために行われ、「Q」の「D」を入力するためにそれらを可能にする。
ここで改善する必要がある現在の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;
}
}
他のヒント
ここに1つのオプションは、方法(「抽出法」)、および使用return
にこのループをリファクタリングすることです。
私が知っている唯一の他の方法は、恐ろしい後藤です。 MSDNにもこのことを言います。に
しかし、私はあなたがこのような場合には、それを使用したいない理由を見ません。あなたが実装されている方法は、罰金を動作し、後藤よりもより保守です。私はあなたが持っているものに保つでしょう。
あなたはマルチレベルのブレークのためのgoto文を使用する必要があります。 C#でのみ「クリーン」な方法であることが表示されます。フラグを使用することも有用であるが、ループを実行するための他の苦境を有する場合、余分なコードを必要とする。
http://msdn.microsoft.com/en -us /ライブラリ/ aa664756(VS.71).aspxのの
いくつかの他の非C言語は、(Pそれは継続...を装った後藤を使用してJavaは、けれども、ちょうど役に立たないようである)break levels;
を行うことによって、マルチレベルのブレークを持っていることに注意することは興味深いかもしれ
なぜループに保つためにブール値を返すメソッドにスイッチをラップしませんか?これは、コードをより読みやすくする副次的な利点を持っているでしょう。誰かが、我々はすべての後の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;
}
フラグは、これを行うための標準的な方法です。私が知っている唯一の他の方法は、goto
を使用することです。
あなたが簡単に外側のループから抜け出すことはできませんが、あなたはそれをcontinue
することができます。
あなたのロジックを逆にした場合、あなたはこれを取得します。
注break
がループを終了するには、switchステートメントの直後にあります。
これは私の意見では非常に読みやすいコードではない、と私はフラグがまだ最高だと思います。
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");
あなたは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)
関数にラップ、それとは、出口にreturn文を使用します。どのようにそれについてはどうですか?
IMO、これはwhile
ループを抜け出しの完全に罰金道です。それはあなたが副作用のない期待しません。私がやって考えることができます。
if(!keepOnLooping)
break;
しかし、その実行の点では何が違うのは本当にありません。
のような書き込み何かます:
case "Exit/Break" :
//Task to do
if(true)
break;
この中断は、どのような場合に関連付けされることはありません。それはwhile
ループに属します。
あなたはのための/ foreachのループにswitch文を変更することができます。いったん条件がfalseに設定し、「keepOnLooping」を満たした後、ループから抜け出すためにブレークを使用しています。残りは自分自身の世話をする必要があります。
もう一つの(それほど大きくない)の代替を一意あなたがすぐ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");
<時間>
(これまでで最もエレガントなソリューションです)新しいメソッドに全体の事をリファクタリングすると、何らかの理由で受け入れられない場合にも、あなたはまた、既存のメソッドの内部で同じことを行うには、匿名デリゲートに頼ることができます。
月か仕事はなく、ラムダは、なぜちょうど楽しみのためにそれに打撃を与えていないことがあります。
while( (expr) => (){
switch(expr){
case 1: dosomething; return true;
case 2 : something;return true;
case exitloop:return false;}
});