2011-09-29 55 views
24

Mi código es el siguiente:caso del interruptor en C# - se espera un valor constante

public static void Output<T>(IEnumerable<T> dataSource) where T : class 
{ 
    dataSourceName = (typeof(T).Name); 
    switch (dataSourceName) 
    { 
     case (string)typeof(CustomerDetails).Name.ToString(); : 
      var t = 123; 
      break; 
     default: 
      Console.WriteLine("Test"); 
    } 
} 

Pero esto no está funcionando. La declaración de caso me está dando un error al decir que se espera una variable constante. Por favor ayuda chicos, gracias!

+0

posible duplicado de [C# - ¿Hay una alternativa mejor que esta para 'activar el tipo'?] (Http://stackoverflow.com/questions/298976/c-is-there-a-better-alternative-than -todo-para-activar-en-tipo) –

Respuesta

20

Ver C# switch statement limitations - why?

declaraciones Básicamente interruptores no puede haber evaluado en la declaración de caso. Deben ser evaluados estáticamente.

+1

Esto no es cierto en VB.net ... Estoy tratando de convertir un código que ya tiene este tipo de valores de caso (básicamente llamadas a métodos) –

+3

@Moslem Ben Dhaou sí C# Switch definitivamente no es equivalente a la declaración de VB Case. Para las sentencias Case, puede usar expresiones (llamadas a funciones, variables, etc.), mientras que C# necesita valores constantes (sin llamadas a funciones, variables, etc.). La declaración de cambio es bastante limitada comparativamente. – deepee1

19

Solo puede hacer coincidir las constantes en las sentencias de cambio.

Ejemplo:

switch (variable) 
{ 
    case 0: 
     //Code 
     break; 
    default: 
     //Code 
     break; 
} 

funciona, pero

switch (variable) 
{ 
    case sameothervarialbe: 
     //Code 
     break; 
    default: 
     //Code 
     break; 
} 

no

+11

Como nota adicional: "const int myConstant = 3" cuenta como una constante, pero "readonly static int myReadonlyStatic = 3" no. – statue

1

interruptor es muy exigente en el sentido de que los valores en el interruptor debe ser una constante de tiempo de compilación. y también el valor que se está comparando debe ser un primitivo (o cadena ahora). Para esto deberías usar una declaración if.

La razón puede volver a la forma en que C los maneja porque crea una tabla de salto (porque los valores son constantes de tiempo de compilación) e intenta copiar la misma semántica al no permitir valores evaluados en sus casos.

3

Johnnie, por favor, vaya a la guía msdn en switch. Además, la especificación de lenguaje C# define claramente el caso de errores en tiempo de compilación:

• Si el tipo de la expresión switch es sbyte, byte, short, ushort, int, uint larga, ulong, bool, char, cadena, o un tipo enum, o si es es el tipo anulable correspondiente a uno de estos tipos, entonces eso es el tipo gobernante de la instrucción switch.

• De lo contrario, exactamente una conversión implícita definida por el usuario (§6.4) debe existir del tipo de la expresión cambio a una de las siguientes posibles tipos de gobierno: sbyte, byte, short, ushort, int, uint long, ulong, char, string, o, un tipo anulable correspondiente a uno de esos tipos.

• De lo contrario, si no existe tal conversión implícita, o si existe más de existe una conversión implícita de este tipo, se produce un error en tiempo de compilación.

Espero que esto ayude.

3

No se puede usar una instrucción switch para esto ya que los valores de casos no se pueden evaluar como expresiones. Para ello hay que utilizar un un if/else ...

public static void Output<T>(IEnumerable<T> dataSource) where T : class 
{ 
    dataSourceName = (typeof(T).Name); 
    if(string.Compare(dataSourceName, typeof(CustomerDetails).Name.ToString(), true)==0) 
    { 
     var t = 123; 
    } 
    else if (/*case 2 conditional*/) 
    { 
     //blah 
    } 
    else 
    { 
     //default case 
     Console.WriteLine("Test"); 
    } 
} 

también me tomé la libertad de poner en orden su sentencia condicional. No hay necesidad de convertir a cadena después de llamar al ToString(). Esto siempre devolverá una cadena de todos modos. Al comparar cadenas para igualdad, tenga en cuenta que usar el operador == dará como resultado una comparación sensible a mayúsculas y minúsculas.Es mejor utilizar string compare = 0 con el último argumento para activar/desactivar mayúsculas y minúsculas.

Cuestiones relacionadas