reflection - 如何从 Case 实例中获取 Discriminated Union Type?

标签 reflection f# discriminated-union

鉴于这两个歧视工会,我想得到 DeclaringType从一个案例来看。

type SingleCaseUnion =
    | One

type MultiCaseUnion =
    | Two
    | Three

每种情况的示例如下:
getDiscriminatedUnionType One = typeof<SingleCaseUnion> // true

getDiscriminatedUnionType Three = typeof<MultiCaseUnion> // true

我的第一次尝试是获取 case 类型并获取它的基类,这是有效的,因为在 F# 中为每个 case 创建了一个子类型。
MultiCaseUnion.Two.GetType().BaseType = typeof<MultiCaseUnion> // true

但是,对于单个 case union 这不起作用,因为没有创建嵌套类型。
SingleCaseUnion.One.GetType().BaseType = typeof<SingleCaseUnion> // false

我的第二次尝试,旨在获得更强大的解决方案是使用 FSharp 反射助手。
FSharpType.GetUnionCases(unionValue.GetType()).First().DeclaringType

这确实适用于所有情况,但它必须为每种情况生成 UnionCaseInfo 实例,这似乎有些不必要。

是否有内置的东西我可能错过了?就像是:
FSharpValue.GetUnionFromCase(SingleCaseUnion.One)

最佳答案

怎么样

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

关于reflection - 如何从 Case 实例中获取 Discriminated Union Type?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41255133/

相关文章:

scala - 函数式语言(Erlang、F#、Haskell、Scala)

f# - 比较歧视工会

java - 通过反射访问main方法中的局部变量

web - 如何在dart中获取当前调用函数的名称?

java - 如何在java反射中从可变数量的参数中获取方法

.net - 现有 ETW 提供程序的 System.Diagnostic.Tracing.EventListener

c# - 设置可为 null 的日期时间的属性值

f# - F# 中的预处理器指令对缩进敏感吗?

f# - 展开 F# 单例区分联合元组类型

javascript - 期待并集和交集的类型错误