简体   繁体   English

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

[英]F#: How to get the type of an instance of an empty discriminated union case using Reflection?

I read the answers of those questions: 我读了这些问题的答案:

But I found out something surprising about the underlying type of discriminated unions: 但是我发现歧视工会的基本类型令人惊讶:

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

Hence my question how I can discriminate a case based on the type when a case is empty? 因此,我的问题是当案件为空时如何根据类型区分案件?

There is no way to distinguish between two union cases with no parameters based on type, because their type in compiled .NET code is the same. 无法根据类型区分没有参数的两个并集情况,因为它们在已编译的.NET代码中的类型是相同的。 You can see that this is the case by slightly tweaking your example: 您可以通过稍微调整示例来看到这种情况:

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

The F# compiler compiles Union1 as a class with a numerical Tag field. F#编译器将Union1编译为带有数字Tag字段的类。 For cases with no additional parameters like A and B here, it will just create an instance of Union1 and set the Tag field to 0 or 1 . 对于没有其他参数(如此处的AB ,它将仅创建Union1的实例并将Tag字段设置为01

When you have a union case with additional parameters, then the compiler generates a new inherited class that then stores values of these parameters (which is why you get a different type for Union2.B ). 当您具有带有附加参数的联合用例时,编译器将生成一个新的继承类,该类将存储这些参数的值(这就是为什么您为Union2.B获得不同类型的Union2.B )。

From the F# perspective, values of a discriminated union have the same type (even if the way DUs are compiled means that the type can sometimes be an inherited class), so there is no reason to expect that you would be able to distinguish cases based on a type - if you have a case where you need this, you should probably reconsider your approach. 从F#角度来看,有区别的并集的值具有相同的类型(即使DU的编译方式意味着该类型有时可以是继承的类),因此没有理由期望您能够区分基于个案的情况。在类型上-如果您有需要的话,则可能应该重新考虑您的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM