如何使用反射来确定F#联合类型是否为枚举式联合(每种情况下都没有字段) [英] How can I use reflection to determine if an F# union type is an enum-like union (no fields in each case)

查看:32
本文介绍了如何使用反射来确定F#联合类型是否为枚举式联合(每种情况下都没有字段)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

术语

在以下文章中,我将使用术语引用枚举"来引用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆