如何宣布可以为空的歧视联盟?

use*_*180 2 f#

我有一个像这样的歧视联盟

type foo =
| Yes of bool
| Number of decimal
Run Code Online (Sandbox Code Playgroud)

我有另一种类型,我试图将这个DS作为一个可以为空的成员

type test(value) =
member this.Value : Nullable<foo> = value
Run Code Online (Sandbox Code Playgroud)

当我尝试这样做时,我得到"一个泛型构造要求类型"foo"有一个公共默认构造函数.我该如何解决这个问题?

The*_*Fox 7

.NET的Nullable<T>类型实际上是设计用于值类型,int而不是与引用类型一起使用,例如string它们已经可以为空.

默认情况下,受歧视的联合是引用类型,因为它们实际上已编译为类.但它们可能被迫成为一个结构,这将使它成为一种价值类型.但是,当你这样做时,你会得到另一个错误:If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.您可以在每个案例中命名值,如下例所示:

[<Struct>]
type foo =
| Yes of yes:bool
| Number of number:decimal
Run Code Online (Sandbox Code Playgroud)

现在你可以拥有一个Nullable<foo>.但你可能实际上并不想这样做.F#中表示参考和值类型的"可为空"值的常规方法是使用Option类型.因此foo,您应该更改类型Option<foo>而不是构建结构:

type test(value) =
    member this.Value : Option<foo> = value

test(Some (Number 1M)) // some value
test(None) // no value
Run Code Online (Sandbox Code Playgroud)

F#很大程度上使得F#中定义的类型不可能为null,因此您将使用Option所有内容而不是区分引用和值类型.Nullable仅对使用它的现有.NET代码非常有用.