如何使用反射来确定F#联合类型是否为枚举式联合(每种情况下都没有字段)

时间:2019-01-25 20:01:03

标签: reflection f#

术语

对于以下文章,我将使用术语“引用枚举”来引用F#类型,该类型是在每种情况下都没有字段的已区分联合。例如:

type AReferenceEnum = Yes | No | Maybe

要求

我需要一个给定Type并返回bool的函数,该函数指示类型是否为引用枚举

给出以下类型:

type AReferenceEnum = Yes | No | Maybe

type ARecord = { name : string }

type AUnion = This of int | That of (int * string)

type AEnum = Left = 1 | Right = 2

该函数将返回这些值

isReferenceEnum typeof<AReferenceEnum> -> true

isReferenceEnum typeof<ARecord> -> false

isReferenceEnum typeof<AUnion> -> false

isReferenceEnum typeof<AEnum> -> false

我尝试过的事情

似乎可以使用FSharpType名称空间中的FSharpValueFSharp.Reflection来完成实现。

我知道您可以检查FSharpType.IsUnion t来检查类型是否是包含引用枚举的并集。

我知道您可以检查FSharpType.GetUnionCases t以获得UnionCaseInfo[]来描述联合类型的不同情况。

我知道您可以检查FSharpValue.GetUnionFields (value, type)来获取value是其中一个实例的案例的字段,而不是其他案例。

如果我可以迭代联合的每个案例的字段,那么我可以检查所有案例都具有0个字段,然后将该类型作为参考枚举。

有什么建议吗?

1 个答案:

答案 0 :(得分:5)

这将通过您的测试用例:

let isReferenceEnum ty = 
    if FSharpType.IsUnion ty then
        FSharpType.GetUnionCases ty
        |> Array.forall (fun i -> i.GetFields().Length = 0)
    else
        false
相关问题