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?
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
    I would like to propose something even more concise:
open Microsoft.FSharp.Reflection
type Coffee = { Country: string; Intensity: int }
type Beverage =
    | Tea
    | Coffee of Coffee
    member x.GetName() = 
        match FSharpValue.GetUnionFields(x, x.GetType()) with
        | (case, _) -> case.Name  
When union case is simple, GetName() may bring the same as ToString():
> let tea = Tea
val tea : Beverage = Tea
> tea.GetName()
val it : string = "Tea"
> tea.ToString()
val it : string = "Tea"
However, if union case is fancier, there will be a difference:.
> let coffee = Coffee ({ Country = "Kenya"; Intensity = 42 })
val coffee : Beverage = Coffee {Country = "Kenya"; Intensity = 42;}
> coffee.GetName()
val it : string = "Coffee"
> coffee.ToString()
val it : string = "Coffee {Country = "Kenya";        Intensity = 42;}"
    来源:https://stackoverflow.com/questions/1259039/what-is-the-enum-getname-equivalent-for-f-union-member