16

この質問は、スイッチについて頭の中にある古い未回答の質問を思い出させました。

    int personType = 1;
    switch (personType)
    {
        case 1:
            Employee emp = new Employee();
            emp.ExperienceInfo();
            break;
        case 2:
            Employee emp = new Employee(); 
            //Error: A local variable named 'emp' is already defined in this scope
            emp.ManagementInfo();
            break;
        case 3:
            Student st = new Student();
            st.EducationInfo();
            break;
        default:
            MessageBox.Show("Not valid ...");
    }

「ケース 2」で emp が認識されるのはなぜですか? C++ では (私が間違っていなければ) 複数のケースを一緒に使用できますが、C# ではそれは不可能でありcase 1、break で閉じる必要があるため、次のコードは C++ では正しく、C# では間違っているように見えます。

case 1:
case 2:
   SomeMethodUsedByBothStates();

そのような振る舞いができないのに、なぜ emp を宣言してcase 1で見ることができるのcase 2でしょうか? 2 つのケースが同時に発生しない場合、オブジェクトが両方で表示される必要があるのはなぜですか?

4

4 に答える 4

34

ケースは、c++ または c# でスコープを作成しません。ケース内で宣言されたこれらの変数はすべて、switch ステートメントと同じスコープ内にあります。これらの変数を特定のケースに対してローカルにする場合は、中括弧を使用する必要があります。

switch (personType)
{
    case 1: {
        Employee emp = new Employee();
        emp.ExperienceInfo();
        break;
    }
    case 2: {
        Employee emp = new Employee(); 
        // No longer an error; now 'emp' is local to this case.
        emp.ManagementInfo();
        break;
    }
    case 3: {
        Student st = new Student();
        st.EducationInfo();
        break;
    }
    ...
}
于 2012-12-05T13:29:50.943 に答える
5

あなたが示した 2 番目のコードは、ケース 2 にbreakorがあると仮定すると、C# では完全に問題ありませんreturn

case 1:
    // no code here...
case 2:
    SomeMethodUsedByBothStates();
    break;

空のケースは通り抜けることができます。
許可されていないのは、失敗する case-branch にコードを含めることです。したがって、以下は無効になります。

case 1:
    SomeMethodUsedOnlyByCase1();
    // no break here...
case 2:
    SomeMethodUsedByBothStates();
    break;

範囲に関する質問は別のものです。基本的に、スコープは case-branch ではなく、switch ステートメント自体です。

サンプルをコンパイルするには、中かっこを追加してケースブランチに独自のスコープを与えるだけです。

int personType = 1;
switch (personType)
{
    case 1:
    {
        Employee emp = new Employee();
        emp.ExperienceInfo();
        break;
    }
    case 2:
    {
        Employee emp = new Employee(); 
        emp.ManagementInfo();
        break;
    }
    case 3:
    {
        Student st = new Student();
        st.EducationInfo();
        break;
    }
    default:
        MessageBox.Show("Not valid ...");
}
于 2012-12-05T13:29:23.607 に答える
2

ケース内で変数を宣言するときは、中括弧を使用して指定します。

int personType = 1;
switch (personType)
{
    case 1: 
   {
     ///
     break;
   }
    case 2: 
   {
     ///
     break;
    }
    case 3: 
   {
        ///
        break;
   }
    ...
}
于 2012-12-05T13:35:16.473 に答える
0

スコープはまったく奇妙ではありません。ローカル変数のスコープは、それが定義されているポイントから、それが定義されているブロックの終わりまでです。したがって、さまざまな変数はそれぞれ、ステートメントの後のempで始まり、対応する で終わるブロックの終わりまでスコープ内にあります。ラベルについて特別なことは何もありません。変数のスコープを変更しません。{switch}case

于 2012-12-05T14:05:06.030 に答える