私には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++;
これは機能しませんか?
さて、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
基本的に、変数宣言はあなたが考えるよりも効果的に広いです。 2番目の例は、宣言されている(より広い)が実際には割り当てられていないため、「明確な割り当て」の影響を受けます。したがって、++
は、割り当てられていない値には意味がありません。
wantcase
あたりのスコープの場合は、それを行うことができます...中括弧を追加するだけです:
switch (x)
{
case 1:
{
uint cId = (uint)3;
break;
}
case 2:
{
uint cId = (uint)5;
break;
}
}
それは少し厄介ですか?はい。直感に反しますか?はい。変更されることはありますか?あり得ないことですが、これは重大な重大な変更であり、既存のC#の多くがコンパイルできなくなるためです。