【问题标题】:Allowing nulls on a record type F#在记录类型 F# 上允许空值
【发布时间】:2015-05-15 14:19:59
【问题描述】:

我正在尝试为 MongoDB C# 驱动程序创建一个类型扩展,当尝试执行产生 0 个结果的查询时,它将返回一个选项类型而不是 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 类型对于互操作而言非常“可为空”,并且每当您尝试查询产生 0 个结果的 MongoDB 集合时,它将返回为 null。我试图设置属性[&lt;AllowNullLiteral&gt;] 但不幸的是它只适用于类。所以唉,我被困住了,我可以将Entity 改为一个类,但我认为记录更符合 F# 的习惯。

【问题讨论】:

    标签: mongodb generics f# extension-methods


    【解决方案1】:

    我认为以下应该可行:

    [<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 的帖子中借用了这个想法: https://sergeytihon.wordpress.com/2013/04/10/f-null-trick/

    【讨论】:

    • 是的,这行得通。这是一个有点时髦的解决方案,但它确实有效。谢谢!
    【解决方案2】:

    在不装箱的情况下进行空值检查的替代方法:

    [<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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-13
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      相关资源
      最近更新 更多