2012-09-14 21 views
8

Supongamos que tengo un montón de campos estáticos y quiero utilizarlos en el interruptor:declaración final de carrera con campos estáticos

public static string PID_1 = "12"; 
public static string PID_2 = "13"; 
public static string PID_3 = "14"; 

switch(pid) 
{ 
    case PID_1: 
     //Do something 1 
     break; 
    case PID_2: 
     //Do something 2 
     break; 
    case PID_3: 
     //Do something 3 
     break; 
    default: 
     //Do something default 
     break; 
} 

Puesto que C# no permite la declaración no constante en el interior del interruptor. Quiero entender cuál es la intención de este tipo de diseño. ¿Cómo debo hacer algo como arriba en C#?

+2

serán los valores de PID_1 PID_2 etc cambiar? –

+0

Sr.Mindor. No, pero quiero que sean estáticos también. – Ashutosh

+1

@Ashutosh Todos los valores 'const' son efectivamente' estáticos'. No están vinculados a una instancia de la clase.No usas 'static' porque es redundante, no porque no sea posible. – Servy

Respuesta

16

Parece que esos valores de cadena deberían ser constantes.

public const string PID_1 = "12"; 
public const string PID_2 = "13"; 
public const string PID_3 = "14"; 

Si eso no es una opción (que en realidad se cambian en tiempo de ejecución), entonces usted puede refactorizar que la solución en una serie de if/else if.

En cuanto a por qué las declaraciones de casos deben ser constantes; al tenerlos constantes, permite que la declaración esté mucho más optimizada. En realidad, es más eficiente que una serie de sentencias if/else if (aunque no de forma espectacular, por lo que si no tiene lotes de comprobaciones condicionales que tardan mucho tiempo). Generará el equivalente de una tabla hash con los valores de declaración de caso como claves. Ese enfoque no podría usarse si los valores pueden cambiar.

+0

Ok. Entonces, ¿por qué no podemos usar campos readonly? usar const no es una opción. Tener una estática pública tiene más sentido para los identificadores constantes ... No puedo usarlos en cualquier lugar que desee y solo tengo una instancia de esto ... – Ashutosh

+2

@Ashutosh No puede usar campos de solo lectura porque el valor no se conoce hasta tiempo de ejecución; la sentencia 'switch' dará como resultado que se genere una tabla en * compile time *, razón por la cual todas las sentencias case deben ser constantes de tiempo de compilación. '" Tener una estática pública tiene más sentido "' Si los valores son realmente constantes, no estoy de acuerdo. Usar un valor 'const' tiene mucho más sentido si los valores son realmente constantes. Tenga en cuenta que todos los valores 'const' son efectivamente' estáticos'. No están vinculados a una instancia del objeto en absoluto. – Servy

2

El argumento del caso debe ser constante en tiempo de compilación.

Intente utilizar const lugar:

public const string PID_1 = "12"; 
public const string PID_2 = "13"; 
public const string PID_3 = "14"; 
+0

@Henk: ¡Gracias! Qué tonto error :) – abatishchev

3

... C# no permite la declaración no constante interruptor dentro ...

Si no puede utilizar:

public const string PID_1 = "12"; 
public const string PID_2 = "13"; 
public const string PID_3 = "14"; 

puede utilizar un diccionario :)

.... 
public static string PID_1 = "12"; 
public static string PID_2 = "13"; 
public static string PID_3 = "14"; 



// Define other methods and classes here 

void Main() 
{ 
    var dict = new Dictionary<string, Action> 
    { 
    {PID_1,()=>Console.WriteLine("one")}, 
    {PID_2,()=>Console.WriteLine("two")}, 
    {PID_3,()=>Console.WriteLine("three")}, 
    }; 
    var pid = PID_1; 
    dict[pid](); 
} 
+0

Estaba escribiendo esto. –

1

Supongo que hay una razón por la que no declaró esas variables como const. Dicho esto:

La declaración switch es solo una abreviatura de un grupo de declaraciones if/else if. Así que si usted puede garantía de quePID_1, PID_2 y PID_3 se no ser igual, lo anterior es equivalente a esto:

if (pid == PID_1) { 
    // Do something 1 
} 
else if (pid == PID_2) { 
    // Do something 2 
} 
else if (pid == PID_3) { 
    // Do something 3 
} 
else { 
    // Do something default 
} 
+0

La activación de cadenas también podría implementarse como un diccionario (https://stackoverflow.com/a/3366497/616827). – Jeff

1

La forma canónica de abordar esto - si sus campos estáticos no son en realidad constantes - es usar un Dictionary<Something, Action>:

static Dictionary<string, Action> switchReplacement = 
    new Dictionary<string, Action>() { 
     { PID_1, action1 }, 
     { PID_2, action2 }, 
     { PID_3, action3 }}; 

// ... Where action1, action2, and action3 are static methods with no arguments 

// Later, instead of switch, you simply call 
switchReplacement[pid].Invoke(); 
Cuestiones relacionadas