2010-02-02 18 views
9

Tengo un tipo de enumeración define así:cómo enumerar una enumeración/tipo en Fa #

type tags = 
    | ART = 0 
    | N = 1 
    | V = 2 
    | P = 3 
    | NULL = 4 

hay una manera de hacer un for ... in tags do?

Este es el error que estoy recibiendo:

El valor, constructor, espacio de nombres o tipo tags no se define

+2

eso no es un enum, es una unión. –

+0

si necesita una enumeración, consulte http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html#_Toc245030918 –

Respuesta

5

Uso Enum.GetValues:

let allTags = Enum.GetValues(typeof<tags>) 
+0

Debe ser Enum.GetValues ​​(typeof ). Lo había intentado antes pero no conocía la sintaxis diferente para typeof. ¡Gracias! – Jared

+3

esto no funcionará porque las etiquetas no son una enumeración, es una unión ... –

+0

el código que proporcionó primero ** no ** funcionó contra el código que Jared publicó. Si otro lector se topa con esta pregunta, habría pensado que Enum.GetValues ​​podría funcionar con sindicatos, lo que no es el caso. Ahora que me explicaste revertí mi -1 –

2

Para haz que sea una enumeración que necesites dar valores explícitos a cada caso; de lo contrario, es un tipo de unión:

type tags = 
    | ART = 0 
    | N = 1 
    | V = 2 
    | P = 3 
    | NULL= 4 
let allTags = System.Enum.GetValues(typeof<tags>) 
2

Robert tiene razón acerca de cómo generar una enumeración real y obtener sus casos. Si tiene un verdadero tipo de unión, puede obtener los casos a través de la función Microsoft.FSharp.Reflection.FSharpType.GetUnionCases.

6

Aquí hay un ejemplo completo que imprime información sobre cualquier unión discriminada. Muestra cómo obtener casos de la unión discriminada y también cómo obtener los campos (en caso de que los necesite). La declaración de tipo de función imprime de la unión discriminada dada:

open System 
open Microsoft.FSharp.Reflection 

let printUnionInfo (typ:Type) = 
    printfn "type %s =" typ.Name 
    // For all discriminated union cases 
    for case in FSharpType.GetUnionCases(typ) do 
    printf " | %s" case.Name 
    let flds = case.GetFields() 
    // If there are any fields, print field infos 
    if flds.Length > 0 then 
     // Concatenate names of types of the fields 
     let args = String.concat " * " [ for fld in flds -> fld.PropertyType.Name ] 
     printf " of %s" args 
    printfn ""  

// Example 
printUnionInfo(typeof<option<int>>) 
+0

La pregunta era sobre enums, sindicatos no discriminados. – jason

+2

La declaración de tipo original en la publicación (antes de su edición) era una unión discriminada, sin embargo ... Enumeraciones son por supuesto útiles en F # también, pero en algunas situaciones. –

+0

La única edición que hice en la publicación fue corregir un error tipográfico de "enumeración" a "enumeración". Creo que basándome en el tema que el OP siempre tuvo la intención de que la pregunta sea sobre enumeraciones, pero introdujo confusión al definir "etiquetas" incorrectamente como una enumeración. – jason

1

Puede utilizar Enum.GetValues, que devuelve una Array de objetos que luego tiene que abatido a valores enteros. (Nota:. Estoy usando C# aplicación de Mono, tal vez las cosas son diferentes con .NET)

Estas son algunas de las funciones que he escrito para obtener una lista de todos los valores de la enumeración y para obtener los valores mínimos y máximos:

open System 

module EnumUtil = 

    /// Return all values for an enumeration type 
    let EnumValues (enumType : Type) : int list = 
     let values = Enum.GetValues enumType 
     let lb = values.GetLowerBound 0 
     let ub = values.GetUpperBound 0 
     [lb .. ub] |> List.map (fun i -> values.GetValue i :?> int) 

    /// Return minimum and maximum values for an enumeration type 
    let EnumValueRange (enumType : Type) : int * int = 
     let values = EnumValues enumType 
     (List.min values), (List.max values) 
0
type Options = 
    | Exit   = 0 
    | CreateAccount = 1 

Console.WriteLine() 
Console.WriteLine("Choose an option:") 
let allOptions = Enum.GetValues(typeof<Options>) 
for option in allOptions do 
    if (option <> null) then 
     Console.WriteLine(sprintf "%d: %s" (option :?> int) (option.ToString())) 
let optionChosen = System.Console.ReadLine() 
Cuestiones relacionadas