F#:如何使用Reflection获得一个空的,有区别的联合案例的实例类型?

时间:2019-06-08 22:58:14

标签: reflection f#

我阅读了这些问题的答案:

但是我发现歧视工会的基本类型令人惊讶:

type Union1 =
    | A
    | B 

type Union2 =
    | A
    | B of int

[<EntryPoint>]
let main argv =
    printfn "%A" (Union1.A.GetType())
    printfn "%A" (Union1.B.GetType())

    printfn "%A" (Union2.A.GetType())
    printfn "%A" (Union2.B(32).GetType())
    0
Program+Union1
Program+Union1
Program+Union2+_A
Program+Union2+B

因此,我的问题是当案件为空时如何根据类型区分案件?

1 个答案:

答案 0 :(得分:7)

由于基于.NET编译的代码的类型相同,因此无法区分没有参数的两个并集情况。您可以通过稍微调整示例来了解这种情况:

type Union1 = A | B     
Union1.A.GetType() = Union1.B.GetType() // Returns 'true'

F#编译器将Union1编译为带有数字Tag字段的类。对于此处没有其他参数(例如AB)的情况,它将仅创建Union1的实例并将Tag字段设置为0或{{ 1}}。

当您具有带有附加参数的联合用例时,编译器将生成一个新的继承类,该类将存储这些参数的值(这就是为什么您为1使用不同类型的原因)。

从F#角度来看,有区别的联合的值具有相同的类型(即使DU的编译方式意味着该类型有时可以是继承的类),因此没有理由期望您能够根据类型区分案例-如果您有需要的案例,则可能应该重新考虑您的方法。