2009-12-22 10 views
7

Me interesan las consideraciones de estilo y rendimiento. Mi elección es para hacer cualquiera de las siguientes situaciones (lo siento por los pobres formato, pero la interfaz de este sitio no es WYSIWYG):.NET C# switch statement string comparar versus comparación enum

Uno:

string value = "ALPHA"; 

switch (value.ToUpper()) 
{ 
    case "ALPHA": 
    // do somthing 
    break; 
    case "BETA": 
    // do something else 
    break; 
    default: 
    break; 
} 

Dos:

public enum GreekLetters 
{ 
    UNKNOWN= 0, 
    ALPHA= 1, 
    BETA = 2, 
    etc... 

} 

string value = "Alpha"; 
GreekLetters letter = (GreekLetters)Enum.Parse(typeof(GreekLetters), value.ToUpper()); 

switch(letter) 
{ 
    case GreekLetters.ALPHA: 
     // do something 
     break; 
    case GreekLetters.BETA: 
     // do something else 
     break; 
    default: 
     break; 
} 

Personalmente, Prefiero la opción DOS a continuación, pero no tengo ninguna razón real aparte de las razones de estilo básico. Sin embargo, ni siquiera estoy seguro de que realmente haya una razón de estilo. Gracias por tu contribución.

+0

Se haría una gran pregunta de la entrevista - me gustaría sugerir que sólo se iba a encontrar con seguridad por perfiles, ya que dependerá de la evolución de 'Enum.Parse()' - por supuesto, la opción dos es más fácil de mantener desde una perspectiva de error tipográfico, incluso si el rendimiento es comparable ... –

+0

+1 para marcar el valor enum de 0 como "desconocido". –

Respuesta

4

La opción n. ° 1 es más rápida porque si look at the code para Enum.Parse, verá que revisa cada elemento uno por uno, buscando una coincidencia. Además, hay menos código para mantener y mantener la coherencia.

Una palabra de precaución es que no debe usar ToUpper, sino más bien ToUpperInvariant() debido a Turkey Test problemas.

Si insiste en la Opción # 2, al menos use la sobrecarga que le permite especificar ignorar mayúsculas y minúsculas. Esto será más rápido que convertirlo a mayúsculas usted mismo. Además, tenga en cuenta que Framework Design Guidelines recomienda que todos los valores enum sean PascalCase en lugar de SCREAMING_CAPS.

+2

En serio, SCREAMING_CAPS es tan cónico C++ –

9

La segunda opción es marginalmente más rápida, ya que la primera opción puede requerir una comparación de cadena completa. Sin embargo, la diferencia será demasiado pequeña para medir en la mayoría de las circunstancias.

La ventaja real de la segunda opción es que ha hecho explícito que los valores válidos para value caen en un rango estrecho. De hecho, arrojará una excepción al Enum.Parse si el valor de la cadena no está en el rango esperado, que a menudo es exactamente lo que usted desea.

+0

La segunda opción es más lenta porque requiere un reflejo para reunir todos los campos y luego una comparación elemento por elemento. Señalo el código fuente del marco en mi respuesta para demostrar esto. –

1

Definitivamente diría # 1. Enum.Parse() provoca una reflexión que es relativamente costosa. Además, Enum.Parse() arrojará una excepción si no está definida y, dado que no hay TryParse(), deberá envolverlo en el bloque Try/Catch

2

No puedo hacer ningún comentario sobre el rendimiento de la pregunta pero en cuanto al estilo prefiero la opción n. ° 2. Cada vez que tengo un conjunto conocido de valores y el conjunto es razonablemente pequeño (menos de un par de docenas más o menos) prefiero usar una enumeración. Encuentro que una enumeración es mucho más fácil de trabajar que una colección de valores de cadena y cualquiera que mire el código puede ver rápidamente cuál es el conjunto de valores permitidos.

0

No estoy seguro de si hay una diferencia de rendimiento al activar un valor de cadena frente a una enumeración.

Una cosa a considerar es si necesitaría los valores utilizados para los enunciados de casos en cualquier parte de su código. Si es así, entonces usar una enumeración tendría más sentido ya que tiene una definición singular de los valores. Las cuerdas de Const también podrían ser utilizadas.

2

Esto realmente depende del número de elementos en la enumeración, y usted tendría que probarlo para cada situación específica, no es probable que haga una gran diferencia. Pero es una gran pregunta.

Con muy pocos valores, el Enum.Parse tomará más tiempo que cualquier otra cosa en cualquier ejemplo, por lo que el segundo debería ser más lento.

Con valores suficientes, la instrucción switch se implementará como una tabla hash, que debería funcionar a la misma velocidad con cadenas y enums, así que de nuevo, Enum.Parse probablemente hará que la segunda solución sea más lenta, pero no tanto.

En algún lugar en el medio, yo esperaría que el coste de la comparación de secuencias es más alta que la comparación de las enumeraciones haría que la primera solución más rápida.

ni siquiera me sorprendería si fuera diferente en diferentes versiones del compilador o diferentes opciones.

Cuestiones relacionadas