-2

重複の可能性:
c#switchステートメントでの変数宣言
Switchの場合の余分な中括弧の目的は何ですか?

今日、私は小さなコードを書いていましたが、デバッグ時にVSが私を叩き、ローカル変数の名前に大きな間違いを犯したと言いました。「「i」という名前のローカル変数はすでにこのスコープで定義されています」。

MyEnum enumerator = MyEnum.B;

switch (enumerator)
{
    case MyEnum.A:
        Int32 i = 0;
        // DoStuffsA();
        break;

    case MyEnum.B:
        Double i = 0D;
        // DoStuffsB();
        break;
}

それで、「OK VS、すぐに修正させてください。もっと気に入ったので、最初にケースのスコープを設定したいと思います!」と言いました。だから私は化粧品を変更しました...しかし突然VSはそのエラーについて泣き言を言うのをやめました:

MyEnum enumerator = MyEnum.B;

switch (enumerator)
{
    case MyEnum.A:
    {
        Int32 i = 0;
        // DoStuffsA();
        break;
    }

    case MyEnum.B:
    {
        Double i = 0D;
        // DoStuffsB();
        break;
    }
}

わかりました...私は「スコープ」の意味を知っており、そのように2つの異なるスコープを作成したことを知っています。問題は、switchステートメントがILコードにどのように変換されるかわからないことです。中括弧が使用されているかどうかに関係なく、すべてのcaseステートメントがswitchスコープに配置されると常に考えていました。だから...次の奇妙なことをコンパイルすることができますよね?

MyEnum enumerator = MyEnum.B;

switch (enumerator)
{
    case MyEnum.A:
        String s = "Hello!";
        Console.WriteLine(s);
        break;

    case MyEnum.B:
        s = "Goodbye!";
        Console.WriteLine(s);
        break;
}

しかし、次のものではありません:

MyEnum enumerator = MyEnum.B;

switch (enumerator)
{
    case MyEnum.A:
    {
        String s = "hello";
        Console.WriteLine(s);
        break;
    }

    case MyEnum.B:
    {
        s = "goodbye";
        Console.WriteLine(s);
        break;
    }
}

この状況でのコンパイラの動作をよりよく説明できる人がいますか?どうもありがとう!

4

3 に答える 3

6

{}異なるcaseブロックにを追加すると、スコープが導入されます。

それらがないと、すべてのcaseブロックが1つのスコープ内にあります。

を使用する最後の2つの例ではs、最初の例は問題ありません。forsで宣言されているcaseようMyEnum.Aに、で使用できますがMyEnum.B、中かっこを使用すると、の宣言はMyEnum.A独自のスコープ内にあり、外部には表示されませMyEnum.Bs。不明であり、新たに宣言する必要があります。

于 2013-01-18T11:21:45.123 に答える
5

まず、ILへの変換はやや無関係です。ILには、スコープの同じ概念はまったくありません。これはすべてC#言語仕様に関するものです。

非常に単純です。ローカル変数のスコープは宣言されたブロックであり、同じ名前の別のローカル変数がスコープ内にある場合、1つのローカル変数を宣言することはできません。

  • 最初のコードスニペットでは、のスコープはiswitchステートメント全体です。i2番目の宣言は、同じスコープ内の別の変数を宣言しようとするため、失敗します。

  • 2番目のコードスニペットでは、各i変数のスコープは中括弧によって作成されたブロックにすぎません。これらは完全に別個のスコープにあり、ネストされていないため、問題ありません。

  • 3番目のコードスニペットでsは、スコープがswitchステートメント全体であるため、変数は2番目のケースのスコープ内にあります。したがって、この変数を使用しても問題ありません。

  • コードの4番目のスニペットでは、変数sは宣言されたブロックのスコープ内にのみ存在するため(ケースA内)、ケースBのスコープ内にはありません。

ただし、3番目のコードスニペットのようなコードは使用しないことを強くお勧めします。それは多くの人々を混乱させるでしょう。複数のケースのスコープにある変数が本当に必要な場合は、switchステートメントの前に宣言します。

于 2013-01-18T11:23:02.823 に答える
-1

中かっこのbreak内側があると、中かっこの端まで壊れ、その時点で中かっこcaseが通り抜けます。break中かっこ以外のステートメントが必要です。例えば

case MyEnum.A:
{
    String s = "hello";
    Console.WriteLine(s);
}
break;
于 2013-01-18T11:22:30.437 に答える