I want to get the equivalent of Enum.GetName
for an F# discriminated union member. Calling ToString()
gives me TypeName+MemberName, which isn't exactly what I want. I could substring it, of course, but is it safe? Or perhaps there's a better way?
To get the value of enum we can simply typecast it to its type. In the first example, the default type is int so we have to typecast it to int. Also, we can get the string value of that enum by using the ToString() method as below.
The enum can be of any numeric data type such as byte, sbyte, short, ushort, int, uint, long, or ulong. However, an enum cannot be a string type.
We can convert an enum to string by calling the ToString() method of an Enum.
You need to use the classes in the Microsoft.FSharp.Reflection
namespace so:
open Microsoft.FSharp.Reflection ///Returns the case name of the object with union type 'ty. let GetUnionCaseName (x:'a) = match FSharpValue.GetUnionFields(x, typeof<'a>) with | case, _ -> case.Name ///Returns the case names of union type 'ty. let GetUnionCaseNames <'ty> () = FSharpType.GetUnionCases(typeof<'ty>) |> Array.map (fun info -> info.Name) // Example type Beverage = | Coffee | Tea let t = Tea > val t : Beverage = Tea GetUnionCaseName(t) > val it : string = "Tea" GetUnionCaseNames<Beverage>() > val it : string array = [|"Coffee"; "Tea"|]
@DanielAsher's answer works, but to make it more elegant (and fast? because of the lack of reflection for one of the methods), I would do it this way:
type Beverage = | Coffee | Tea static member ToStrings() = Microsoft.FSharp.Reflection.FSharpType.GetUnionCases(typeof<Beverage>) |> Array.map (fun info -> info.Name) override self.ToString() = sprintf "%A" self
(Inspired by this and this.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With