سؤال

أريد الحصول على ما يعادل Enum.GetName لعضو الاتحاد الائتماني للتمييز. دعا ToString() يعطيني typeName + اسم عضو، وهو ليس بالضبط ما أريد. أستطيع أن أسترجها، بالطبع، لكن هل هي آمنة؟ أو ربما هناك طريقة أفضل؟

هل كانت مفيدة؟

المحلول

تحتاج إلى استخدام الفصول في 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  

عندما حالة الاتحاد بسيطة، 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