web-dev-qa-db-ja.com

中括弧付き/なしのC#Switchステートメント....違いは何ですか?

C#では、_case:_ステートメントの間のswitch()ステートメント内で中括弧を省略することが常に許可されていますか?

JavaScriptプログラマーがよく行うように、それらを省略することの効果は何ですか?

例:

_switch(x)
{
  case OneWay:
  {                               //  <---- Omit this entire line
    int y = 123;
    FindYou(ref y);
    break;
  }                               //  <---- Omit this entire line
  case TheOther:
  {                               //  <---- Omit this entire line
    double y = 456.7; // legal!
    GetchaGetcha(ref y);
    break;
  }                               //  <---- Omit this entire line
}
_
68

中括弧は必要ありませんが、新しい宣言スペースを導入するのに便利です。私の知る限り、この動作はC#1.0から変更されていません。

それらを省略することの効果は、switchステートメント内のどこかで宣言されたすべての変数が、すべてのcaseブランチを通して宣言のポイントから見えることです。

Eric Lippertの例も参照してください(投稿のケース3):

4つのスイッチの異常

エリックの例:

switch(x)
{
  case OneWay:
    int y = 123;
    FindYou(ref y);
    break;
  case TheOther:
    double y = 456.7; // illegal!
    GetchaGetcha(ref y);
    break;
}

int yおよびdouble yは、switchステートメントによって導入された同じ宣言スペースにあります。中括弧を使用して宣言スペースを区切ることにより、エラーを修正できます。

switch(x)
{
  case OneWay:
  {
    int y = 123;
    FindYou(ref y);
    break;
  }
  case TheOther:
  {
    double y = 456.7; // legal!
    GetchaGetcha(ref y);
    break;
  }
}
102
Dirk Vollmar

中括弧は switch block のオプション部分であり、switchセクションの一部ではありません。中かっこは、スイッチセクション内に挿入するか、コードのスコープを制御するためにどこにでも等しく挿入できます。

これらは、switchブロック内のスコープを制限するのに役立ちます。例えば:

int x = 5;

switch(x)
{
case 4:
    int y = 3;
    break;
case 5:
    y = 4;
    //...                      
    break;
}

対...

int x = 5;

switch(x)
{
  case 4:
  {
    int y = 3;
    break;
  }
  case 5:
  {
    y = 4;//compiling error
    //...                      
    break;
  }
}

注:C#では、使用する前に、最初の例のケース5ブロック内で値をyに設定する必要があります。これは、偶発的な変数フォロースルーに対する保護です。

14
Brian R. Bondy

スイッチ内部のブレースは、実際にはスイッチ構造の一部ではありません。これらはスコープブロックにすぎず、好きな場所でコードに適用できます。

それらを持つことと持たないことの違いは、各ブロックがそれ自身のスコープを持っていることです。スコープ内でローカル変数を宣言できます。これは、別のスコープ内の他の変数と競合しません。

例:

int x = 42;
{
  int y = x;
}
{
  int y = x + 1; // legal, as it's in a separate scope
}
8
Guffa

これらは厳密に必要というわけではありませんが、ローカル変数の宣言を開始するとすぐに(スイッチブランチで)非常に推奨されます。

これは機能しません:

    // does not compile
    switch (x)
    {
        case 1 :               
            int j = 1;
            ...
            break;

        case 3:
            int j = 3;   // error
            ...
            break;
    }

これはコンパイルされますが、不気味です:

    switch (x)
    {
        case 1 :               
            int j = 1;
            ...
            break;

        case 3:
            j = 3;
            ...
            break;
    }

だからこれは最高です:

  switch (x)
    {
        case 1 : 
         {             
            int j = 1;
            ...
         }
         break;  // I prefer the break outside of the  { }

        case 3: 
         {
            int j = 3;
            ...
         }
         break;
    }

シンプルで読みやすいものにしてください。読者に真ん中の例に含まれるルールの詳細な知識を要求する必要はありません。

4
Henk Holterman