4

次のC#を検討してください。

// C# .net
switch(x)
   {
    case 1:
        for(int i = 0; i < 10; i++)
        {
            int val = getValue(i);
            if (val == 0)
                goto endswitch;
        }
        doMoreStuff();
        break;
    case 2:
        doSomeThingElse();
        break;
    default: throw new ArgumentOutOfRangeException();
}
endswitch: ;

上記のコードサンプルに似たコードを作成しました。問題は、内側のforループの内側からswitchステートメントを壊す必要があることです。そこにステートメントを置くbreakと、内部のforループが壊れてから、に進むだけdoMoreStuff()です。これは私が必要としていることではありません。

ここで最もうまくいくと思われる代替案はgoto声明ですが、私はこれが嫌われていることを知っています。

もう1つの方法は、forループ内の別の変数を追跡することですが、これによりコード行が追加され、効率が低下します。

これを行うための最良の方法は何ですか?

更新: JavaScriptでこれを行う方法があることを読みました。これは次のように機能します:(http://www.devguru.com/technologies/ecmascript/quickref/break.html)

// JavaScript
outer_loop:
for(i=0; i<3; i++)
{
   document.write("<BR>" + "outer " + i + ":   ");
   for(j=0; j<5; j++)
   {
      document.write("inner " + j + " ");
      if(j==x)
         break outer_loop;
   }
}

このようなことはC#で可能ですか?

4

2 に答える 2

7

チェックを戻りフラグのあるメソッドに抽象化できます。

switch(x)
{
    case 1:
        if (ShouldDoMoreStuff())
            doMoreStuff();
        break;
    case 2:
        doSomeThingElse();
        break;
    default: throw new ArgumentOutOfRangeException();
}


private bool ShouldDoMoreStuff()
{
    for(int i = 0; i < 10; i++)
    {
        var val = getValue(i);
        if (val == 0)
            return false;
    }

    return true;
}

拡張するだけで、gotoをそのまま使用できますが、特にそのような些細なケースでは、一般的に眉をひそめます。 ネストされたループやスイッチが多数ある場合に役立つことがありますが、これは通常、少しリファクタリング/再設計する必要があることを示しています。ご指摘のとおり、ローカル変数を格納してチェックを行うことはできますが、気付いたようにそれは少し鈍い/臭いです。上で投稿したこの方法は、かなり読みやすくなるので、私はこの方法を好みます。

編集:あなたのコメントと編集された質問に関して、私はあなたのJavaScriptコードに類似した言語機能がC#に存在するとは思わない。http://msdn.microsoft.com/en-us/library/37zc9d2w%28VS.80%29.aspxから(強調を追加):

ネストされたステートメント内では、breakステートメントは、それをすぐに囲むdo、for、switch、またはwhileステートメントのみを終了します。returnまたはgotoステートメントを使用して、より深くネストされた構造内から制御を移すことができます。

于 2012-07-05T17:30:11.017 に答える
0

これは、考えすぎることによって引き起こされるタイプの問題です。forループの前に条件が満たされた場合に変更されるブール値を単純に作成し、ブール値がtrueの場合にのみメソッドを実行できます。例:

switch(x)
   {
    case 1:
        bool donrun;
        for(int i = 0; i < 10; i++)
        {
            int val = getValue(i);
            if (val == 0)
                donrun = true;
        }
        if(!donrun) doMoreStuff();
        break;
    case 2:
        doSomeThingElse();
        break;
    default: throw new ArgumentOutOfRangeException();
}
于 2012-07-05T19:00:50.217 に答える