2012-04-10 15 views
56

私はこの事について興味が...例を参照してください。Switchの大文字小文字の目的は何ですか?

switch(x) 
{ 
    case(a): 
     { 
     //do stuff 
     } 
     break; 
    case(b): 
     //do stuff 
     break; 
} 

にすべての私の人生を私はケースbのようにそれをやったが、C#は私がそれを使用することができ、およびVisual Studioは私が崩壊することができますので、その事、私は好奇心が強いです - ケースa(中カッコ)とケースbの実際の違いは何ですか?

+15

ケースAで定義された変数はそのブロックでのみ表示されていることを除いて違いはありません。 –

+3

本当に何もありません。ケースにスコープされているオブジェクトを作成して使用することが時々あります。角かっこなしでは、あなたが見る範囲が広いことを定義するものは何もありません。 – Robinson

+1

あなたが尋ねたものではありませんが、長い 'case'ブロックが読みにくいことがわかりました。スコープやその他の複雑さが必要な場合は、新しいメソッドを取得します。 –

答えて

71

中括弧{}は、一連の操作の範囲を定義するために使用されます。奇妙なことに、以下はコンパイルして動作します:

private void ConnectionStateChange(object sender, StateChangeEventArgs e) 
{ 
    string s = "hi"; 
    switch(s) 
    { 
     case "hi": 
      { 
       int a = 1; 
       a++; 
      } 
      { 
       int a = 2; 
       a++; 
      } 
      break; 
    } 

    { 
     int a = 1; 
     a++; 
    } 
    { 
     int a = 2; 
     a++; 
    } 
} 

ご覧のとおり、私は4つの変数を作成しました。ローカル変数としては、それぞれ独自のスコープ内にしか存在しないため、それぞれは完全に独立しています。

これは意味がありますか?

+0

+1非常に興味深いデモンストレーションです。 – SouthShoreAK

+0

よく説明され、本当にこれを感謝します! – Wish

+55

どうして奇妙なのですか?それはかなり普通に見えます(しかし、人工的です)。 – Joey

30

新しい変数を作成できる新しいスコープが作成されます。

13

これは、使用した変数の新しいスコープを作成します。変数の範囲は時々トリッキーになることがあります。たとえば、あなたが掲示したコードの中で。

switch(x) 
{ 
    case(a): 
     { 
     int i = 0; 
     } 
     break; 
    case(b): 
     i = 1; // Error: The name 'i' doesn't exist in the current context 
     break; 
} 

エラーが範囲の外にアクセスさcase(b)変数aのように、ここで理にかなっています。一方では、

switch(x) 
{ 
    case(a): 
     { 
     int i = 0; 
     } 
     break; 
    case(b): 
     int i = 1; // Error: A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else 
     break; 
} 

上記の2つのエラーは、互いに矛盾しています。これを回避するには、

switch(x) 
{ 
    case(a): 
     { 
     int i = 0; 
     } 
     break; 
    case(b): 
     { 
     int i = 1; // No error 
     } 
     break; 
} 

エリックリペットはcase文で変数のスコープを説明するために非常に良いlink to his blogを共有し、両方のcase文で別々に範囲を定義する必要があります。あなたはそれを見ておくべきです。

77

括弧の対(不ブラケットから[] - なく、括弧から() - しかし括弧{})その中にゼロまたはそれ以上のステートメントでは、C#で法的ステートメントであり、したがって声明が法的に表示される場所にはどこにでも出現することがあります。

他の人が指摘したように、このような文は、それの中に宣言されたローカル変数のスコープを定義する新しいローカル変数宣言スペースを、導入しているため、そのようにするための典型的な理由があります。 (要素の「スコープ」は要素は、その非修飾名によって参照することが可能なプログラム・テキストの領域であることを思い出してください。)私は、これはswitch声明ために特に興味があることに注意して

スイッチ内の有効範囲の規則は少し奇妙です。彼らはどのように奇妙なの詳細は、「ケース3:」を参照してください件名に私の記事で:

http://ericlippert.com/2009/08/13/four-switch-oddities/

+1

+1の真のソースです。 –

+0

私はいつも、Cスイッチはプログラミングにおいてもっと奇妙で問題の多い構成要素の1つであるため、C#がよりスマートなスイッチステートメントを導入しなかったことに失望しました。 –

+6

@ NateC-K:C#*はより良いswitch文を導入しました! C#の設計者は、C/C++ switch文の欠点を綿密に調べ、多くの点で改善しました。例:(1) "no fall through"ルールは共通のバグの原因を取り除きます。 (2)文字列をオンにすることができます。 (3)ヌル可能型をオンにすることができます。 (4)ケースラベルの種類は、スイッチの支配的なタイプと互換性があるかどうかチェックされます。 (5) "goto case 1"はC++とは異なり、正しく動作します。等々;ほとんどすべての考えられる方法でC#スイッチが改善されています。 –

関連する問題