Pourquoi est-ce que dans une instruction switch C #, pour une variable utilisée dans plusieurs cas, vous ne la déclarez que dans le premier cas?
Par exemple, ce qui suit renvoie l'erreur "Une variable locale nommée 'variable' est déjà définie dans cette étendue".
switch (Type)
{
case Type.A:
string variable = "x";
break;
case Type.B:
string variable = "y";
break;
}
Cependant, selon la logique, la déclaration initiale ne doit pas être atteinte si le type est Type.B
. Toutes les variables d'une instruction switch existent-elles dans une seule étendue et sont-elles créées/allouées avant le traitement de toute logique?
Je crois que cela a à voir avec la portée globale de la variable, c'est une portée au niveau du bloc qui est définie au niveau du commutateur.
Personnellement, si vous définissez une valeur sur quelque chose à l'intérieur d'un commutateur dans votre exemple pour qu'elle soit vraiment utile, vous voudrez quand même la déclarer en dehors du commutateur.
Si vous voulez une variable limitée à un cas particulier, enfermez simplement le cas dans son propre bloc:
switch (Type)
{
case Type.A:
{
string variable = "x";
/* Do other stuff with variable */
}
break;
case Type.B:
{
string variable = "y";
/* Do other stuff with variable */
}
break;
}
Oui, la portée est l'ensemble du bloc de commutation - malheureusement, l'OMI. Cependant, vous pouvez toujours ajouter des accolades dans un seul cas pour créer une portée plus petite. Quant à savoir si elles sont créées/allouées - le cadre de pile a suffisamment d'espace pour toutes les variables locales dans une méthode (en laissant de côté la complexité des variables capturées). Ce n'est pas comme si cet espace était alloué pendant l'exécution de la méthode.
Parce que leur portée est au bloc de commutation. Spécification du langage C # indique ce qui suit:
La portée d'une variable ou constante locale déclarée dans un bloc commutateur est le bloc commutateur.
Les variables partagent la portée dans le compilateur C #. Cependant, la portée n'existe pas de la même manière dans CIL . Quant à la création/initialisation réelle ... le modèle de mémoire .NET permet au compilateur de déplacer les lectures/écritures un peu aussi longtemps que des règles simples sont suivies, sauf si la variable est marquée comme volatile .