2011-08-25 21 views
18

Estaba trabajando en un método de servicio web que recibirá una matriz de entradas como parámetro, y luego, dentro del método, convertí los valores en la matriz en valores enum, y los almacené en una lista enum. Sin embargo, cuando se pasa un valor que no está en la enumeración, se agrega a la lista de enumeración sin problemas. No InvalidCastException, nada. Hice un proyecto de prueba que tiene este aspecto:C# enumeración enum aceptando un valor incorrecto

static class Program 
{ 
    static void Main(string[] args) 
    { 
     List<TestValues> values = new List<TestValues>() { 
      TestValues.Value1, 
      TestValues.Value2, 
      (TestValues)15 
     }; 

     foreach (var val in values) 
      Console.WriteLine(val); 

     Console.Read(); 
    } 

    enum TestValues 
    { 
     Value1 = 2, 
     Value2 = 4, 
     Value3 = 8 
    } 
} 

Cuando lo ejecuto, la salida es:

Value1 
Value2 
15 

Por mi servicio web, voy a poner en práctica una validación, así que esto nunca va a hapen en absoluto. Pero ... ¡esto es extraño! ¿No debería el tiempo de ejecución arrojar un InvalidCastException o ArgumentOutOfRangeException, o algo similar? Como obtuve una lista de enumeraciones (y no de valores int), quiero que los valores se limiten a los valores de la enumeración (para eso sirve una enumeración).

¿Echo de menos algo? ¿Es esto un error de .NET, un error de C# o hay algo que no sé con enumeraciones?

+0

1 para la pregunta gazapo – Tigran

+1

Leer éste: [¿Por qué fundición int al valor de enumeración no válido NO tirar excepción?] [1] [1]: http://stackoverflow.com/ questions/6413804/why-does-casting-int-to-invalid-enum-value-not-throw-exception – vinayvasyani

Respuesta

19

Puede asignar cualquier valor a enum que permita el tipo subyacente. De forma predeterminada, el tipo subyacente es int, por lo que puede asignar cualquier valor int al enum.

La razón principal de esto es porque si usted tiene una enumeración [Flags], que quieren para poder asignar valores compuestos:

[Flags] 
public enum MyFlags 
{ 
    A = 1, 
    B = 2 
} 

MyFlags flags = (MyFlags)3; // Equivalent to setting A and B 

Preferentemente que acaba haría uso de los valores de la enumeración de hacer eso, sin embargo:

MyFlags flags = MyFlags.A | MyFlags.B; // Sets flags to 3 

es importante tener en cuenta, por supuesto, que el atributo [Flags] no está obligado a permitir que esta asignación. Todos enum s tienen esta propiedad, por diseño.

Según lo señalado por varias personas, puede usar Enum.IsDefined() para determinar si un valor particular es válido para un determinado enum. Eso debería ayudar con su validación.

+0

Me olvidé completamente de '[Flags]', ya que rara vez lo uso. Para mí, parece una clara ventaja para ese uso, pero un poco extraño para el uso más común de enums. Por cierto, los comentarios y las otras respuestas proporcionan enlaces complementarios agradables al tema. – Raphael

1

Siempre puede convertir cualquier valor int en una enumeración basada en int. Esto es por diseño, ya que el elenco sería mucho más lento si tuviera que verificar todos los valores legales.

+1

No creo que la velocidad fuera el factor decisivo aquí. –

+0

@Henk - por favor elabore, ¿hay algún otro factor además de Flags? –

1

Para determinar si el int especificado se define dentro del enum, puede usar Enum.IsDefined.

Enum.IsDefined(typeof(TestValues), 15); 
5

Sí, no hay ningún control para los valores definidos al convertir a un valor enum.

Usted puede utilizar el método IsDefined para comprobar si se ha definido un valor específico:

if (Enum.IsDefined(typeof(TestValues), value)) ...