2011-02-09 15 views
8

Actualmente estoy leyendo el libro C# 4.0 in a Nutshell, que, por cierto, creo que es un excelente libro, incluso para los programadores avanzados para utilizarlo como una buena referencia.Enum.IsDefined con enum encendidos

Estaba mirando hacia atrás en los capítulos sobre los conceptos básicos, y me encontré con un truco para decir si se define un cierto valor en un Enum al usar enumeraciones marcadas.
El libro afirma que el uso de Enum.IsDefined no funciona en enumeraciones marcados, y sugiere una solución alternativa como esta:

static bool IsFlagDefined(Enum e) 
{ 
    decimal d; 
    return (!decimal.TryParse(e.ToString(), out d); 
} 

Esto debería devolver cierto si un determinado valor se define en una enumeración que está marcado.

¿Puede alguien explicarme por qué funciona?

Gracias de antemano :)

+0

como un lado hay otro caso donde Enum.IsDefined podría comportarse diferente de lo esperado (o tal vez eso es predeterminado (T)). Enum.IsDefined (predeterminado (T)) puede devolver true y _false_. por defecto (T) (donde T es una enumeración) siempre devuelve (T) 0, por lo que si T no tiene un valor válido para (T) 0, el resultado es falso. ¿Me han engañado al menos una vez –

Respuesta

12

Básicamente, llamando ToString cualquier valor enum de un tipo declarado con el atributo [Flags] devolverá algo como esto para cualquier valor definido:

SomeValue, SomeOtherValue 

Por otra parte , si el valor es no definido dentro del tipo enum, entonces ToString simplemente producirá una representación de cadena del valor de ese valor entero valor, por ejemplo .:

5 

Así que lo que esto significa es que si se puede analizar la salida de ToString como un número (no estoy seguro por qué el autor eligió decimal), no se define dentro del tipo.

Aquí hay un ejemplo:

[Flags] 
enum SomeEnum 
{ 
    SomeValue = 1, 
    SomeOtherValue = 2, 
    SomeFinalValue = 4 
} 

public class Program 
{ 
    public static void Main() 
    { 
     // This is defined. 
     SomeEnum x = SomeEnum.SomeOtherValue | SomeEnum.SomeFinalValue; 

     Console.WriteLine(x); 

     // This is not (no bitwise combination of 1, 2, and 4 will produce 8). 
     x = (SomeEnum)8; 

     Console.WriteLine(x); 
    } 
} 

La salida del programa anterior es:

 
SomeOtherValue, SomeFinalValue 
8 

para que pueda ver cómo funciona el método sugerido.

+0

Should SomeEnum.SomeValue = 0? – PaulB

+0

@PaulB: puede ser. ¿Estás preguntando porque normalmente hay un valor 'Ninguno' para 0? Eso es verdad y probablemente menos confuso. Tal vez actualice la respuesta solo para no tirar a nadie. –

+0

Sí, solo que no puede representar SomeValue con ninguna de las otras ... Gracias por cambiar :) – PaulB

0

Si el valor de e no se puede crear utilizando una combinación de indicadores ToString() tiene como valor predeterminado un número entero. Y los números enteros, por supuesto, analizarán como decimal.

Pero por qué su código analiza como decimal no es del todo claro para mí. Pero probablemente los tipos integrales no funcionarán para ambos enum s basados ​​en Int64 y UInt64.