문제

나는 동등한 것을 얻고 싶다 Enum.GetName F# 식별 노조 회원의 경우. 부름 ToString() 내가 원하는 것이 아닌 typeName+memberName을 제공합니다. 물론 그것을 구할 수는 있지만 안전합니까? 아니면 더 나은 방법이 있습니까?

도움이 되었습니까?

해결책

당신은 클래스를 사용해야합니다 Microsoft.FSharp.Reflection 네임 스페이스 :

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의 답변은 작동하지만 더 우아하게 (그리고 빠르고, 방법 중 하나에 대한 반사가 없기 때문에) 이런 식으로 할 것입니다.

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

(에서 영감을 받다 이것 그리고 이것.)

더 간결한 것을 제안하고 싶습니다.

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  

Union 사건이 단순한 경우 GetName() 동일하게 가져올 수 있습니다 ToString():

> let tea = Tea
val tea : Beverage = Tea

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

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

그러나 노조 사건이 더 좋아지면 차이가있을 것입니다.

> 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;}"
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top