2012-01-30 25 views
6

tengo una enumeración de la siguiente maneraConvertir en Enum subyacente tipo

type Suit = 
    |Clubs = 'C' 
    |Spades = 'S' 
    |Hearts = 'H' 
    |Diamonds = 'D' 

¿Cómo puedo obtener el valor subyacente de carbón si se le da valor de enumeración? por ejemplo tengo Suit.Clubs y desea obtener 'C'

+0

'vamos ch = (traje de cuadro):? > char' parece funcionar, pero espero que haya una solución más elegante que no implique el boxeo ... – ildjarn

Respuesta

11

como otra opción

type Suit = 
    |Clubs = 'C' 
    |Spades = 'S' 
    |Hearts = 'H' 
    |Diamonds = 'D' 

let c = Suit.Clubs 
let v : char = LanguagePrimitives.EnumToValue c 

Editado: Comparación de diferentes enfoques:

type Suit = 
    |Clubs = 'C' 
    |Spades = 'S' 
    |Hearts = 'H' 
    |Diamonds = 'D' 

let valueOf1 (e : Suit) = LanguagePrimitives.EnumToValue e 
let valueOf2 (e : Suit) = unbox<char> e 
let valueOf3 (e : Suit) = (box e) :?> char 

Y bajo el capó:

.method public static 
    char valueOf1 (
     valuetype Program/Suit e 
    ) cil managed 
{ 
    // Method begins at RVA 0x2050 
    // Code size 3 (0x3) 
    .maxstack 8 

    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: ret 
} // end of method Program::valueOf1 


.method public static 
    char valueOf2 (
     valuetype Program/Suit e 
    ) cil managed 
{ 
    // Method begins at RVA 0x2054 
    // Code size 13 (0xd) 
    .maxstack 8 

    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: box Program/Suit 
    IL_0007: unbox.any [mscorlib]System.Char 
    IL_000c: ret 
} // end of method Program::valueOf2 

.method public static 
    char valueOf3 (
     valuetype Program/Suit e 
    ) cil managed 
{ 
    // Method begins at RVA 0x2064 
    // Code size 13 (0xd) 
    .maxstack 8 

    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: box Program/Suit 
    IL_0007: unbox.any [mscorlib]System.Char 
    IL_000c: ret 
} // end of method Program::valueOf3 
+0

¿Hay alguna desventaja al uso de 'LanguagePrimitives.EnumToValue'? P.ej. ¿Utiliza la reflexión internamente? – ildjarn

+0

editado mi respuesta – desco

+0

Excelente, muy completo. +1 – ildjarn

4

Puede utilizar las funciones del módulo LanguagePrimitives:

// Convert enum value to the underlying char value 
let ch = LanguagePrimitives.EnumToValue Suit.Clubs 

// Convert the char value back to enum 
let suit = LanguagePrimitives.EnumOfValue ch 

EDIT: no vi estas funciones en mi primer intento de respuesta, por lo la primera vez que sugirió el uso de:

unbox<char> Suit.Clubs 

Esto es más corto que lo Ildjarn sugiere en un comentario, pero tiene el mismo problema - no hay ninguna comprobación de que realmente esté convirtiendo al tipo correcto. Con EnumToValue, no puede cometer este error, ya que siempre devuelve el valor del tipo subyacente correcto.

+2

Estaba sorprendido cuando 'let ch = char suit' no funcionó; Supuse que se generó un operador de conversión explícito para el tipo subyacente para las enumeraciones. – ildjarn