【问题标题】:How do you get the Discriminated Union Type from a Case instance?您如何从案例实例中获取可区分联合类型?
【发布时间】:2017-05-06 10:13:06
【问题描述】:

鉴于这两个有区别的联合,我想从案例实例中获取DeclaringType

type SingleCaseUnion =
    | One

type MultiCaseUnion =
    | Two
    | Three

每种情况的示例如下:

getDiscriminatedUnionType One = typeof<SingleCaseUnion> // true

getDiscriminatedUnionType Three = typeof<MultiCaseUnion> // true

我的第一次尝试是获取案例类型并获取它的基类,这是因为在 F# 中为每个案例创建了一个子类型。

MultiCaseUnion.Two.GetType().BaseType = typeof<MultiCaseUnion> // true

但是,对于单个 case 联合,这不起作用,因为没有创建嵌套类型。

SingleCaseUnion.One.GetType().BaseType = typeof<SingleCaseUnion> // false

我的第二次尝试是使用 FSharp Reflection 助手,旨在获得更强大的解决方案。

FSharpType.GetUnionCases(unionValue.GetType()).First().DeclaringType

这对所有情况都有效,但它必须为每种情况生成 UnionCaseInfo 实例,这似乎有些不必要。

是否有一些我可能错过的内置功能?比如:

FSharpValue.GetUnionFromCase(SingleCaseUnion.One)

【问题讨论】:

    标签: reflection f# discriminated-union


    【解决方案1】:

    怎么样

    open FSharp.Reflection
    type FSharpType =
        static member GetUnionType t =         
            let ownType = t.GetType()
            assert FSharpType.IsUnion(ownType)
            let baseType = ownType.BaseType        
            if baseType = typeof<System.Object> then ownType else baseType
    

    测试:

    (FSharpType.GetUnionType MultiCaseUnion.Three).Name //MultiCaseUnion
    
    (FSharpType.GetUnionType SingleCaseUnion.One).Name //SingleCaseUnion
    

    【讨论】:

    • 这可能是目前最好的解决方案。但是,它不要求类型是可区​​分联合。
    • AFAIK,没有办法限制联合类型。虽然添加为断言。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    • 2020-04-30
    • 2017-09-18
    • 1970-01-01
    • 2017-11-18
    相关资源
    最近更新 更多