2012-09-13 19 views
6

¿Por qué se compila el siguiente código? Esperaría que se queje de que foo no se haya declarado en la segunda sucursal. ¿El compilador maneja la declaración de modo que esté dentro del alcance de todos los casos?¿Por qué las variables que se declaran en una declaración de caso están en el alcance para otros casos?

using System; 

namespace Scratch 
{ 
    class Scratch 
    { 
     public static void Main() 
     { 
      var x = 2; 
      switch (x) 
      { 
       case 1: 
        var foo = "one"; 
        Console.Out.WriteLine(foo); 
        break; 
       case 2: 
        foo = "two"; // is foo in scope here? 
        Console.Out.WriteLine(foo); 
        break; 
      } 
     } 
    } 
} 
+0

que desee ver http://stackoverflow.com/questions/11199338/using-a-switch-statement-to-set-the-value-of-one-particular-variable-only – nawfal

Respuesta

8

Lo que dijo @JonSkeet es correcto: Un "bloque" en el sentido C/C++/C# no es lo mismo que un "caso" en el sentido lógico. Pero no mencionó la "mejor práctica" para solucionar el problema: si desea declarar una variable dentro de un caso de una declaración de cambio, es una buena práctica ajustar todo el "caso" lógico en un bloque. De esta forma, el "caso" lógico y el "alcance" real reconocido por el compilador serán uno y el mismo.

public static void Main() 
{ 
    var x = 2; 
    switch (x) 
    { 
     case 1: { // notice these braces I added 
      var foo = "one"; 
      Console.Out.WriteLine(foo); 
      break; 
     } 
     case 2: 
      foo = "two"; // hooray! foo is no longer in scope here 
      Console.Out.WriteLine(foo); 
      break; 
    } 
} 
+0

Usted vencer ¡Yo a la misma respuesta! – ColinCren

8

¿Por qué compilar el siguiente código?

Debido a que el lenguaje está diseñado de tal manera con muerte cerebral en esta área en particular :(

El alcance de una variable local es el bloqueen el que se declaró, y es accesible en cualquier punto de vista léxico después de la declaración.

no, no me gustaría diseñar el idioma de esa manera tampoco. no soy un fan del diseño del interruptor en C# ...

1

en las variables de C# están en el ámbito a nivel de bloque. Como el bloque sigue al conmutador statemen t, foo está de hecho en el alcance en ambos casos.

3

Para que no compile puede ámbito de aplicación, con las llaves de esta manera:

using System; 

namespace Scratch 
{ 
    class Scratch 
    { 
     public static void Main() 
    { 
     var x = 2; 
     switch (x) 
     { 
      case 1: 
      { 
       var foo = "one"; 
       Console.Out.WriteLine(foo); 
       break; 
      } 
      case 2: 
      { 
       foo = "two"; // is foo in scope here? 
       Console.Out.WriteLine(foo); 
       break; 
      } 
     } 
    } 
} 

Esto obliga a que exista el foo var a sólo dentro de ese ámbito en particular.

Cuestiones relacionadas