2010-05-24 11 views
22

Estoy escribiendo un analizador sintáctico que llama algunas funciones dependiendo de algún valor.¿Diccionario con delegado o switch?

puedo aplicar esta lógica con el interruptor simple como esto:

switch(some_val) 
{ 
    case 0: 
     func0(); 
     break; 
    case 1: 
     func1(); 
     break; 
}  

o con los delegados y un diccionario de esta manera:

delegate void some_delegate(); 
Dictionary<int, some_delegate> some_dictionary = new Dictionary<int, some_delegate>(); 
some_dictionary[0] = func0; 
some_dictionary[1] = func1; 

some_dictionary[some_value].Invoke();  

Son estos dos métodos equivalentes a los que se prefiere?

Respuesta

9

En términos de acceso, están idénticos: ambos sólo asegurarse de que ese valor específico tiene un resultado correspondiente. Sin embargo, un diccionario lanzará una excepción fuera de límites si intenta acceder a una clave inexistente.

La elección debe ser principalmente en la reutilización. Si solo necesita hacer esta lógica de bifurcación en un punto, entonces usar una caja de conmutación probablemente tenga más sentido que almacenar una variable. Si necesita acceder a él repetidamente en puntos separados, utilice el Diccionario para evitar volver a pegar repetidamente la instrucción switch.

+4

También podría usar la alternativa de la vieja escuela para cortar y pegar la programación. Ponga la instrucción switch en un método. –

2

Ambas hacen lo mismo (debe verificar si la llave aparece en el dictonario).

Es solo cuestión de legibilidad. Lo que se ve mejor para usted y más importante, lo que prefieren las personas que leen su código.

(creo que el diccionario)

+0

Gracias por su respuesta. Ahora que ambos hacen lo mismo, en otro caso la pregunta no tendría ningún significado :) –

11

prefiero fuertemente la elección de diccionario, ya que con un inicializador, puede ser mucho más compacto y fácil de leer:

var actions = new Dictionary<int, Action> 
{ 
    {1,() => Console.WriteLine("One!")}, 
    {2,() => Console.WriteLine("Two!")} 
} 

Además, tienen una mayor flexibilidad; puede agregar condiciones y acciones de manera programática, que a menudo es útil, dependiendo de lo que esté haciendo.

+0

¿Qué hay de la velocidad? –

+7

Será más lento que el interruptor. Tenga cuidado allí, sin embargo; La optimización prematura es la fuente de todos los males. Código para un buen diseño, legibilidad y todo ese jazz, y solo trabaje en la parte de velocidad si es demasiado lento para sus propósitos.La diferencia de velocidad puede ser completamente despreciable, pero las diferencias de legibilidad son reales y obvias. –

+0

Gracias, el tiempo no es demasiado crítico para mí en este caso, entonces usaré Dectionary con el delegado –

6

Si el programador típico en su equipo es algo así como los que trato a menudo, debe optar por la opción más simple, es decir, el interruptor. Los delegados me parecen una solución "inteligente" que no es necesaria.

+1

Estoy de acuerdo con ccomet. Si el cambio solo ocurre una vez en su código, entonces es la mejor opción, pero si se duplica en 2 o más métodos, entonces el diccionario es el enfoque más limpio. Los programadores incompetentes o desinteresados ​​son un problema completamente diferente. No creo que sea beneficioso escribir el código del "mínimo común denominador". Si el equipo no está interesado en aprender, entonces consigue un nuevo trabajo. ;) –

+1

@Jacques ¿Por qué no simplemente refactorizar la sentencia switch en un método que ambos llaman? –

0

Si necesita activar cadenas en un archivo de recursos, digamos para propósitos de globalización, entonces deberá usar el enfoque de diccionario/delegado.

4

Me gusta el enfoque del diccionario porque le da la posibilidad de cambiar las expresiones lambda cuando sea necesario. Este es un gran truco para que un programador guarde en su bolsa de herramientas para casos que involucran programas que usan árboles de decisión complejos. Sería muy difícil modificar los bloques de su caja de conmutadores en tiempo de ejecución y la mejor respuesta terminaría involucrando lambdas de todos modos.

Una vez tuve una situación en la que necesitaba crear una sentencia de conmutación de forma dinámica. Este método proporcionó una solución mucho más legible.