在记录类型 F# 上允许空值

Allowing nulls on a record type F#

我正在尝试为 MongoDB C# 驱动程序进行类型扩展,当尝试执行产生 0 个结果的查询时,它将 return 一个选项类型而不是 null。

我已经 运行 解决了几个问题,但现在只有一件事阻碍了。

这是代码

[<Extension>]
type Utils () =
    [<Extension>]
    static member inline tryFindOne(x: MongoCollection<'T>, query) =
        match x.FindOne(query) with
        | null -> None
        | value -> Some value

[<CLIMutable>]
type Entity = 
    { Id : ObjectId; Name : string }
    static member Create(name) =
        { Id = ObjectId(); Name = name }

问题当然是F#编译器的记录类型Entity不符合扩展方法的类型约束('T : null),但我必须要有约束能够针对空值进行模式匹配。当然,这是一种荒谬的事情,因为 Entity 类型非常 "nullable" 用于互操作目的,并且每当您尝试查询 MongoDB 集合时,它都会被 return 编辑为 null产生 0 个结果。我试图设置属性 [<AllowNullLiteral>] 但不幸的是它只适用于 classes。唉,我被困住了,我可以将 Entity 变成 class,但我认为记录更符合 F# 的习惯。

我认为以下应该可行:

[<Extension>]
type Utils () =
[<Extension>]
static member inline tryFindOne(x: MongoCollection<'T>, query) =
    let theOne = x.FindOne(query);
    if (box theOne = null) None else Some(theOne)

我在这里借鉴了 Sergey Tihon 的 post 的想法: https://sergeytihon.wordpress.com/2013/04/10/f-null-trick/

不装箱进行 null 检查的替代方法:

[<Extension>]
type Utils () =
    [<Extension>]
    static member inline tryFindOne(x: MongoCollection<Entity>, query) =
        let theOne = x.FindOne(query)
        if obj.ReferenceEquals(theOne, null) then None else Some(theOne)