1

次のコンパイラ エラーが発生するのはなぜですか。

//エラー CS0159: そのようなラベル 'lbl_proc_20' はありません

次のコードを使用します。

//JUST A DUMMY CODE TO ILLUSTRATE THE CONCEPT
int a = resultOfFunction1();
int b = resultOfFunction2();

//10+ Local variables that are calculated depending on the results above

if (a < 10)
{
    switch (b)
    {
        case 0:
            //Actions for A<10, B=0, using local variables
            break;
        case 1:
            double c = someFunction(a, b);  //In real code involves calculations based on a and b
            if(c > 10.0)
                goto lbl_proc_20;   //error CS0159: No such label 'lbl_proc_20' within the scope of the goto statement

                    //Actions for A<10, B=1, using local variables
            break;
        default:
            //Actions for A<10, B=Other, using local variables
            break;
    }
}
else if (a < 20)
{
lbl_proc_20:
    switch(b)
    {
        case 0:
            //Actions for A<20, B=0, using local variables
            break;
        case 1:
            //Actions for A<20, B=1, using local variables
            break;
        case 2:
            //Actions for A<20, B=2, using local variables
            break;
        default:
            //Actions for A<20, B=Other, using local variables
            break;
    }
}
else if (a < 30)
{
    switch(b)
    {
        case 0:
            //Actions for A<30, B=0, using local variables
            break;
        case 1:
            //Actions for A<30, B=1, using local variables
            break;
        case 2:
            //Actions for A<30, B=2, using local variables
            break;
        default:
            //Actions for A<30, B=Other, using local variables
            break;
    }
}

goto ステートメントでエラーが発生するのはなぜですか? また、それを機能させるにはどうすればよいですか?

編集:実際のコードを示すためにサンプルを変更しました。

4

3 に答える 3

10

gotoのスコープ内のラベルにジャンプするためにのみ使用できますgoto。エラーを説明するドキュメントCS0159から:

goto ステートメントによって参照されるラベルが、goto ステートメントの範囲内で見つかりませんでした。

ifラベルは存在しますが、ブロックからブロックにジャンプすることはできませんelse。内のコードelseは、goto.

必要がないようにコードを再構築する時が来gotoました。

編集

ロジックを単純化するようにしてください。gotoステートメントよりも複数の関数を使用することをお勧めします。

検討すべきオプションの 1 つは、Windows Workflow Foundationです。これは、ロジックをフローチャートとして視覚的に表現できる非常に優れたツールです。WWF は、指定したロジックを処理するために必要なコードを生成します。何らかのタイプの有限状態マシンまたは同様のプロセスを作成しているように見えるため、これはうまくいくかもしれません。

于 2012-09-30T22:08:52.200 に答える
2

「後藤なしでやる方法」への回答として

bool pretendA20 = false;

if (a < 10)
{
    switch (b)
    {
        case 0:
            //Actions for A<10, B=0, using local variables
            break;
        case 1:
            double c = someFunction(a, b);  //In real code involves calculations based on a and b
            if(c > 10.0)
            {
                //goto lbl_proc_20;   
                pretendA20 = true;
                break;
             }

             //Actions for A<10, B=1, using local variables

            break;
        default:
            //Actions for A<10, B=Other, using local variables
            break;
    }
}

if ((a >= 10 && a < 20) || pretendA20)
{
//lbl_proc_20:
    switch(b)
    {
于 2012-09-30T23:07:55.900 に答える
1

C# 言語仕様 (249 ページの第 8 章) には、次のように記載されています。

指定された名前のラベルが現在の関数メンバーに存在しない場合、または goto ステートメントがラベルのスコープ内にない場合、コンパイル時エラーが発生します。この規則は、goto ステートメントを使用して、ネストされたスコープから制御を移すことを許可しますが、ネストされたスコープには移しません。

あなたの場合、ラベルlbl_proc_20はと同じスコープになく、goto別のネストされたスコープに制御を移そうとしています。

ここから言語仕様を取得できます。

http://www.microsoft.com/en-us/download/details.aspx?id=7029

于 2012-09-30T23:02:25.370 に答える