56 votes

Quel est le but de l'appareil dentaire supplémentaire dans le cas de Switch ?

Je suis curieux de cette chose... voir l'exemple :

switch(x)
{
    case(a):
        {
        //do stuff
        }
        break;
    case(b):
        //do stuff
        break;
}

Toute ma vie, je l'ai fait comme la casse b, mais puisque C# me permet de l'utiliser, et que Visual Studio me permet de l'effondrer, je suis curieux - quelle est la différence réelle entre la casse a (avec accolades) et la casse b ?

77voto

Eric Lippert Points 300275

Une paire de bretelles (pas parenthèses -- [] -- et non parenthèses -- () -- mais appareils orthodontiques {} ) contenant zéro ou plusieurs déclarations est une déclaration légale en C#, et peut donc apparaître partout où une déclaration peut légalement apparaître.

Comme d'autres l'ont fait remarquer, la raison typique d'agir ainsi est qu'une telle déclaration introduit une nouvelle espace de déclaration des variables locales qui définit alors le portée des variables locales qui y sont déclarées. (Rappelons que la "portée" d'un élément est la suivante la région du texte du programme dans laquelle l'élément peut être désigné par son nom non qualifié .)

Je note que c'est notamment intéressant dans un switch car les règles de scoping dans un switch sont un peu étranges. Pour plus de détails sur ces règles, voir "Cas 3 :" dans mon article sur le sujet :

http://ericlippert.com/2009/08/13/four-switch-oddities/

71voto

Ian Points 2455

Les accolades {} sont utilisées pour définir la portée d'un ensemble d'opérations. Bizarrement, le texte suivant sera compilé et fonctionnera :

private void ConnectionStateChange(object sender, StateChangeEventArgs e)
{
    string s = "hi";
    switch(s)
    {
        case "hi":
            {
                int a = 1;
                a++;
            }
            {
                int a = 2;
                a++;
            }
            break;
    }

    {
        int a = 1;
        a++;
    }
    {
        int a = 2;
        a++;
    }
}

Comme vous pouvez le voir, dans cette seule méthode, j'ai créé quatre variables, chacune appelée a. Chacune est entièrement distincte car, en tant que variables locales, elles n'existent que dans leur propre périmètre.

Est-ce que ça a un sens ?

30voto

Daniel A. White Points 91889

Il crée une nouvelle portée dans laquelle vous pouvez créer de nouvelles variables.

13voto

hamad Points 2595

Il crée une nouvelle portée pour les variables que vous avez utilisées. La portée des variables peut parfois être délicate. Par exemple, dans le code que vous avez posté ;

switch(x)
{
    case(a):
        {
        int i = 0;
        }
        break;
    case(b):
        i = 1; // Error: The name 'i' doesn't exist in the current context
        break;
}

L'erreur a un sens ici comme dans case(b) variable a est accessible hors du champ d'application. Maintenant, d'un autre côté,

switch(x)
{
    case(a):
        {
        int i = 0;
        }
        break;
    case(b):
        int i = 1; // Error: A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else
        break;
}

Les deux erreurs ci-dessus semblent contradictoires l'une par rapport à l'autre. Pour contourner ce problème, vous devez définir la portée séparément dans les deux déclarations de cas,

switch(x)
{
    case(a):
        {
        int i = 0;
        }
        break;
    case(b):
        {
        int i = 1; // No error
        }
        break;
}

Eric Lippert a partagé un très bon lien vers son blog pour expliquer la portée des variables dans les déclarations de cas. Vous devriez y jeter un coup d'oeil.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X