質問

私は、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;}
});   
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top