如何使用反射来确定F#联合类型是否为枚举式联合(每种情况下都没有字段) [英] How can I use reflection to determine if an F# union type is an enum-like union (no fields in each case)
问题描述
术语
在以下文章中,我将使用术语引用枚举"来引用F#类型,该类型是在每种情况下都没有字段的区分联合.例如:
For the following post, I will use the term "reference enum" to refer to an F# type that is a discriminated union with no fields in each case. For example:
type AReferenceEnum = Yes | No | Maybe
要求
我需要一个给定 Type
并返回 bool
的函数,该函数告诉类型是否为引用枚举.
I need a function that given a Type
, returns a bool
that tells whether the type is a reference enum or not.
给出以下类型:
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
我尝试过的事情
似乎可以使用 FSharp.Reflection
名称空间中的 FSharpType
和 FSharpValue
完成该实现.
It seems like the implementation could be done using FSharpType
and FSharpValue
in the FSharp.Reflection
namespace.
我知道您可以检查 FSharpType.IsUnion t
来检查类型是否为包含引用枚举的并集.
I know you can check FSharpType.IsUnion t
to check if a type is a union, which includes reference enums.
我知道您可以检查 FSharpType.GetUnionCases t
来获取描述联合类型不同情况的 UnionCaseInfo []
.
I know you can check FSharpType.GetUnionCases t
to get a UnionCaseInfo[]
describing the different cases of the union type.
我知道您可以检查 FSharpValue.GetUnionFields(值,类型)
,以获取 value
是实例的情况下的字段,但不能包含其他情况.
I know you can check FSharpValue.GetUnionFields (value, type)
to get the fields of the case that value
is an instance of, but not other cases.
如果我可以迭代联合的每个案例的字段,那么我可以检查所有案例都具有0个字段,然后将其作为引用枚举.
If I could iterate the fields of each case of the union, then I could check that all cases have 0 fields, and then the type would be a reference enum.
有什么建议吗?
推荐答案
这将通过您的测试用例:
This passes your test cases:
let isReferenceEnum ty =
if FSharpType.IsUnion ty then
FSharpType.GetUnionCases ty
|> Array.forall (fun i -> i.GetFields().Length = 0)
else
false
这篇关于如何使用反射来确定F#联合类型是否为枚举式联合(每种情况下都没有字段)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!