name enum f# discriminated-union

¿Cuál es el equivalente Enum.GetName para el miembro de la unión F#?



enum to list c# (3)

Quiero obtener el equivalente de Enum.GetName para un miembro de la unión discriminado por F #. Llamar a ToString() me da TypeName + MemberName, que no es exactamente lo que quiero. Podría subscribirlo, por supuesto, pero ¿es seguro? O tal vez hay una mejor manera?


Debe usar las clases en el espacio de nombres Microsoft.FSharp.Reflection para:

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"|]


La respuesta de @ DanielAsher funciona, pero para hacerlo más elegante (¿y rápido? Debido a la falta de reflexión de uno de los métodos), lo haría de esta manera:

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

(Inspirado por this y this .)


Me gustaría proponer algo aún más conciso:

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

Cuando Union GetName() es simple, GetName() puede traer lo mismo que ToString() :

> let tea = Tea val tea : Beverage = Tea > tea.GetName() val it : string = "Tea" > tea.ToString() val it : string = "Tea"

Sin embargo, si el caso de la unión es más elegante, habrá una diferencia:

> 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;}"