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

Eho*_*ret 1 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
Run Code Online (Sandbox Code Playgroud)
Program+Union1
Program+Union1
Program+Union2+_A
Program+Union2+B
Run Code Online (Sandbox Code Playgroud)

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

Tom*_*cek 7

无法根据类型区分没有参数的两个并集情况,因为它们在已编译的.NET代码中的类型是相同的。您可以通过稍微调整示例来看到这种情况:

type Union1 = A | B     
Union1.A.GetType() = Union1.B.GetType() // Returns 'true'
Run Code Online (Sandbox Code Playgroud)

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

当您具有带有附加参数的并用格时,编译器会生成一个新的继承类,该类将存储这些参数的值(这就是为什么您获得的不同类型的原因Union2.B)。

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