2009-04-02 13 views
9

Considere el siguiente código:¿Hay alguna manera de que el compilador C# muestre advertencias cuando una instrucción switch tiene casos no controlados?

 private enum myEnum 
     { 
      A, 
      B 
     } 
     private void myMethod(myEnum m) 
     { 
      switch (m) 
      { 
       case myEnum.A: 
        //do stuff 
       break; 
       case myEnum.B: 
        //do stuff 
       break; 
       default: 
        throw new NotImplementedException(m.ToString()); 
      } 
     } 

Si alguna vez añadir un tercer miembro de C a MyEnum, sólo será advertido en tiempo de ejecución por un NotImplementedException

Lo que me gustaría hacer es tener el compilador avisarme cuando hay un interruptor con casos no manejados y no predeterminado: caso.

¿Hay alguna manera de hacer eso u otra solución a este problema, el objetivo final es ser advertido en tiempo de compilación de que falta algo?

Respuesta

6

Lamentablemente, no hay una función de compilación para hacer esto por usted.

En lugar de tener una enumeración, tener una clase base o una interfaz. MyMethod se define en la interfaz.

Cada miembro de enum se convierte en una clase con comportamiento diferente para myMethod. Si agrega una clase (para ampliar las opciones, actualmente agregaría un elemento enum) pero no implementa myMethod, obtendrá un error de compilación.

teniendo mucho lugar en el código donde proporciona un comportamiento diferente en las declaraciones de selección es un olor que puede necesitar para usar el polimorfismo.

EDITAR

El mejor consejo que puedo dar es la construcción de pruebas unitarias para cada función que se basa en la sentencia switch, y lo llaman para cada valor de la enumeración (se puede obtener los valores en tiempo de ejecución con el miembro GetValues ​​en la clase Enum)

+0

Eso es un buen punto. Pero en mi situación, no creo que se aplique (llevaría a clases casi vacías, que contienen una lógica que no es de su responsabilidad.Normalmente, tengo algunos DataContracts que contienen un miembro enumerado, y mi GUI enciende esos miembros para ver cómo formatearlos). – Brann

+0

Un buen patrón, pero úselo con cuidado. Si su enumeración es grande y su interruptor solo necesita manejar algunos casos, probablemente no desee crear un trillón de clases. –

+0

+1 para la edición. =) –

1

No, no hay nada en el idioma para verificar esto.

puede ordenar una:

default: 
    throw new ArgumentOutOfRangeException("Invalid value or bug"); 

caso, pero obviamente eso es la ejecución en tiempo en lugar de tiempo de compilación.

1

Nunca lo usó, pero FxCop puede ser útil. Es compatible con la escritura de reglas personalizadas. Por supuesto, eso no es una verificación en tiempo de compilación, sino algo que puede integrarse en sus procesos.

0

Esto puede convertirse en una pesadilla de mantenimiento, tuvo que pasar un montón de tiempo intentando depurar un valor enum faltante en una declaración de cambio.

Has escrito una pequeña clase para hacer declaraciones de conmutación durante un poco más fácil mantenimiento,

enter image description here

La clase se asegura de que todos los valores de enumeración son bien manejados o explícitamente ignorado, que arroja un NotImplementedExpcetion lo contrario.

Salida del código fuente y más detalles here

Cuestiones relacionadas