J'ai deux fonctions, l'une peut être compilée et l'autre pas. Quelle est la différence?
La fonction numéro 1 suppose-t-elle que le cas 1 sera toujours atteint, ou s'agit-il simplement d'un problème de compilation?
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;
}
}
J'ai essayé bien sûr de rechercher "Déclarer des variables à l'intérieur du boîtier de commutateur en C #", mais pour moi, cela ressemble à une sorte de bogue en C # maintenant, conservé pour une compatibilité descendante.
// Après avoir reçu un avertissement indiquant qu'il a déjà été répondu, ma question peut maintenant être réduite à ce dont il s'agit vraiment.
Pourquoi:
int x;
x++;
ça ne marche pas?
Bien, uint cId
est défini dans {...}
scope ce qui est dans votre cas 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
Dans le second cas variable
est défini, mais étant variable locale doit être initialisé avant utilisation (incrément):
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
Fondamentalement, la déclartion variable est effectivement plus large que vous ne le pensez; le deuxième exemple souffre d'une "affectation définitive" car il est déclaré (plus large), mais pas réellement affecté, donc ++
n'a aucun sens sur une valeur non affectée.
Si vous voulez étendues par case
, vous pouvez le faire ... ajoutez simplement des accolades:
switch (x)
{
case 1:
{
uint cId = (uint)3;
break;
}
case 2:
{
uint cId = (uint)5;
break;
}
}
Est-ce un peu vexant? Oui. Est-ce anti-intuitif? Oui. Sera-t-il jamais changé? Peu probable, car ce serait un changement de rupture significatif qui empêcherait la compilation de beaucoup de C # existants.