Reflection 如何使用反射来确定F#并集类型是否是类似枚举的并集(每种情况下都没有字段)

Reflection 如何使用反射来确定F#并集类型是否是类似枚举的并集(每种情况下都没有字段),reflection,f#,Reflection,F#,术语 在下面的文章中,我将使用术语“reference enum”来指代F#类型,它是一个有区别的并集,在每种情况下都没有字段。例如: type AReferenceEnum = Yes | No | Maybe 要求 我需要一个函数,该函数给定一个类型,返回一个bool,告知该类型是否为引用枚举 鉴于这些类型: type AReferenceEnum = Yes | No | Maybe type ARecord = { name : string } type AUnion = Th

术语

在下面的文章中,我将使用术语“reference enum”来指代F#类型,它是一个有区别的并集,在每种情况下都没有字段。例如:

type AReferenceEnum = Yes | No | Maybe

要求

我需要一个函数,该函数给定一个
类型
,返回一个
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
isReferenceEnum typeof->true
isReferenceEnum类型->错误
isReferenceEnum类型->错误
isReferenceEnum类型->错误

我尝试过的

似乎可以使用
FSharp.Reflection
命名空间中的
FSharpType
FSharpValue
来实现

我知道您可以检查
FSharpType.IsUnion t
以检查类型是否为包含引用枚举的联合

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

我知道您可以检查
FSharpValue.GetUnionFields(value,type)
以获取
value
是其实例的情况下的字段,而不是其他情况下的字段

如果我可以迭代联合的每个案例的字段,那么我可以检查所有案例是否都有0个字段,然后类型将是引用枚举


有什么建议吗?

这通过了您的测试用例:

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

谢谢我不知道UnionCaseInfo.GetFields()。由于某种原因,它没有出现在intellisense中。每当“我们”需要从F#那里得到一些不同寻常的东西时,我都有一种不好的感觉,那就是我们错过了语言的本质。从C/C + C++背景中,我已经问了相当长的一段时间的类似问题,直到我意识到,与C…请问您为什么需要F#提供这样的功能?也许,有一个更简单的解决方案,它与您试图实现的目标完全正交!底线是,您很可能不需要类似于F中的C反射魔法:)我正在尝试为用F编写的web服务生成一个TypeScript客户端。类型的“种类”决定了将其转换为TypeScript时必须使用的策略。我正在用F#写这个生成器。谢谢你的澄清。然后,在深入研究TypeScript生成路线之前,您确实必须了解以下内容:)。那里的生成与使用
[JavaScript]
属性装饰类型一样简单。由于TypeScript是JavaScript的超集,因此它将开箱即用!整洁的只是让它工作了