I've got an enumeration type defined like so:
type tags =
| ART = 0
| N = 1
| V = 2
| P = 3
| NULL = 4
is there a way to do a for... in tags do
?
This is the error that I'm getting:
The value, constructor, namespace or type
tags
is not defined
使用Enum.GetValues
:
let allTags = Enum.GetValues(typeof<tags>)
Here is a complete example that prints information about any discriminated union. It shows how to get cases of the discriminated union and also how to get the fields (in case you needed them). The function prints type declaration of the given discriminated union:
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>>)
How about:
let enumToList<'a> = (Enum.GetValues(typeof<'a>) :?> ('a [])) |> Array.toList
This has the advantage of providing a strongly typed list
To use just do:
let tagList = enumToList<tags>
To make it an enum you need to explicitly give values to each case, otherwise it's a union type:
type tags =
| ART = 0
| N = 1
| V = 2
| P = 3
| NULL= 4
let allTags = System.Enum.GetValues(typeof<tags>)
You can use Enum.GetValues
, which returns an Array
of objects that you then have to downcast to integer values. (Note: I'm using Mono's F# implementation; maybe things are different with .NET.)
Here are some functions I wrote to get a list of all enumeration values and to get the min and max values:
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)
Robert's right about how to generate an actual enum and get its cases. If you have a true union type, you can get the cases via the Microsoft.FSharp.Reflection.FSharpType.GetUnionCases
function.
In.Net 5 there is a generic overload of Enum.GetValues which eliminates the need for casting.
Enum.GetValues<T>()
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.