web-dev-qa-db-ja.com

違いは何ですか、またSwitch CaseはC#でこのように機能するのはなぜですか?

私には2つの関数があり、1つはコンパイルでき、もう1つはコンパイルできません。違いはなんですか?

関数番号1は、ケース1が常にヒットすることを前提としていますか、それとも単なるコンパイラーの問題ですか?

public void Test(int x)
{
    switch (x)
    {
        case 1:
            uint cId = (uint)3;
            break;

        case 2:
            cId = (uint)5; //NO ERROR HERE. WHY?
            break;
    }
}

public void DeclaringInsideSwitch(int x)
{
    uint tst = 0;
    switch (x)
    {
        case 1:
            int y = 3;
            uint variable = tst;
            break;

        case 2:
            variable++; //ERROR HERE. WHY?
            break;
    }
}

もちろん「C#のスイッチケース内で変数を宣言する」を検索しようとしましたが、C#の何らかのバグのように思えますが、下位互換性のために保存されています。

//既に回答済みであるという警告が表示されたら、私の質問を実際の内容に減らすことができます。

なぜ:

int x;
x++;

これは機能しませんか?

24
justromagod

さて、uint cId{...}内で定義されていますscopeこれはあなたの場合switch scope

switch (x)
{
    case 1:
        uint cId = (uint)3; // <- definition 
        break;

    case 2:
        // cId has been defined and thus can be assigned (initialization)
        cId = (uint)5; //NO ERROR HERE WHY?
        break;
}  // <- end of cId scope

2番目の場合、variableが定義されていますが、使用する前にローカル変数初期化済みにする必要があります。

switch (x)
{
    case 1:
        int y = 3;
        uint variable = tst; // <- definition 
        break;
    case 2:
        // variable defined, but has not been initialized ("case 1:" hasn't been run),
        // variable contains trash and so you can't increment it 
        variable++; //ERROR HERE WHY?
        break;
} // <- end of variable scope
17
Dmitry Bychenko

基本的に、変数宣言はあなたが考えるよりも効果的に広いです。 2番目の例は、宣言されている(より広い)が実際には割り当てられていないため、「明確な割り当て」の影響を受けます。したがって、++は、割り当てられていない値には意味がありません。

wantcaseあたりのスコープの場合は、それを行うことができます...中括弧を追加するだけです:

        switch (x)
        {
            case 1:
            {
                uint cId = (uint)3;
                break;
            }
            case 2:
            {
                uint cId = (uint)5;
                break;
            }
        }

それは少し厄介ですか?はい。直感に反しますか?はい。変更されることはありますか?あり得ないことですが、これは重大な重大な変更であり、既存のC#の多くがコンパイルできなくなるためです。

24
Marc Gravell