C # Switch-Anweisung mit / ohne geschweifte Klammern… was ist der Unterschied?

72

Hat C # Ihnen immer erlaubt, geschweifte Klammern in einer switch()Anweisung zwischen den case:Anweisungen wegzulassen ?

Was bewirkt das Weglassen, wie es Javascript-Programmierer oft tun?

Beispiel:

switch(x)
{
  case OneWay:
  {                               //  <---- Omit this entire line
    int y = 123;
    FindYou(ref y);
    break;
  }                               //  <---- Omit this entire line
  case TheOther:
  {                               //  <---- Omit this entire line
    double y = 456.7; // legal!
    GetchaGetcha(ref y);
    break;
  }                               //  <---- Omit this entire line
}
goodguys_activate
quelle

Antworten:

106

Geschweifte Klammern sind nicht erforderlich, können jedoch nützlich sein, um einen neuen Deklarationsbereich einzuführen . Soweit ich weiß, hat sich dieses Verhalten seit C # 1.0 nicht geändert.

Wenn Sie sie weglassen, werden alle Variablen, die irgendwo in der switchAnweisung deklariert sind, von ihrem Deklarationspunkt aus in allen Fallzweigen sichtbar.

Siehe auch das Beispiel von Eric Lippert (Fall 3 im Beitrag):

Vier Schalter Kuriositäten

Erics Beispiel:

switch(x)
{
  case OneWay:
    int y = 123;
    FindYou(ref y);
    break;
  case TheOther:
    double y = 456.7; // illegal!
    GetchaGetcha(ref y);
    break;
}

Dies wird nicht kompiliert, da int yund double ysich im selben Deklarationsbereich befinden, der durch die switchAnweisung eingeführt wurde. Sie können den Fehler beheben, indem Sie die Deklarationsräume mit geschweiften Klammern trennen:

switch(x)
{
  case OneWay:
  {
    int y = 123;
    FindYou(ref y);
    break;
  }
  case TheOther:
  {
    double y = 456.7; // legal!
    GetchaGetcha(ref y);
    break;
  }
}
Dirk Vollmar
quelle
3
+1. Besonders wenn Ihr Switch-Inhalt nicht trivial ist, ist dies WIRKLICH praktisch.
TomTom
14

Die geschweiften Klammern sind ein optionaler Teil des Schalterblocks , sie sind nicht Teil der Schalterabschnitte. Klammern können in Schalterabschnitte oder an einer beliebigen Stelle eingefügt werden, um den Umfang Ihres Codes zu steuern.

Sie können nützlich sein, um den Umfang innerhalb des Schalterblocks zu begrenzen. Zum Beispiel:

int x = 5;

switch(x)
{
case 4:
    int y = 3;
    break;
case 5:
    y = 4;
    //...                      
    break;
}

vs ...

int x = 5;

switch(x)
{
  case 4:
  {
    int y = 3;
    break;
  }
  case 5:
  {
    y = 4;//compiling error
    //...                      
    break;
  }
}

Hinweis: Für C # müssen Sie im ersten Beispiel im Fall 5 einen Wert auf y setzen, bevor Sie ihn verwenden. Dies ist ein Schutz gegen versehentliches Verfolgen von Variablen.

Brian R. Bondy
quelle
10

Die Klammern im Schalter sind eigentlich überhaupt nicht Teil der Schalterstruktur. Es handelt sich lediglich um Bereichsblöcke, die Sie im Code an einer beliebigen Stelle anwenden können.

Der Unterschied zwischen dem Vorhandensein und dem Nichtvorhandensein besteht darin, dass jeder Block seinen eigenen Bereich hat. Sie können lokale Variablen innerhalb des Bereichs deklarieren, die nicht mit anderen Variablen in einem anderen Bereich in Konflikt stehen.

Beispiel:

int x = 42;
{
  int y = x;
}
{
  int y = x + 1; // legal, as it's in a separate scope
}
Guffa
quelle
5

Sie sind nicht unbedingt erforderlich, aber sobald Sie lokale Variablen (in den Switch-Zweigen) deklarieren, werden sie dringend empfohlen.

Das wird nicht funktionieren:

    // does not compile
    switch (x)
    {
        case 1 :               
            int j = 1;
            ...
            break;

        case 3:
            int j = 3;   // error
            ...
            break;
    }

Dies kompiliert, aber es ist gruselig:

    switch (x)
    {
        case 1 :               
            int j = 1;
            ...
            break;

        case 3:
            j = 3;
            ...
            break;
    }

Das ist also am besten:

  switch (x)
    {
        case 1 : 
         {             
            int j = 1;
            ...
         }
         break;  // I prefer the break outside of the  { }

        case 3: 
         {
            int j = 3;
            ...
         }
         break;
    }

Halten Sie es einfach und lesbar. Sie möchten nicht, dass die Leser die Regeln des mittleren Beispiels genau kennen.

Henk Holterman
quelle
"Spooky" ist genau. :)
Neonblitzer