Null Coalescing Operator in F#?

前端 未结 3 1957
长情又很酷
长情又很酷 2020-12-05 02:36

When interacting with C# libraries, I find myself wanting C#\'s null coalescing operator both for Nullable structs and reference types.

Is it possible t

3条回答
  •  心在旅途
    2020-12-05 03:18

    modified the accepted answer by jbtule to support DBNull:

    //https://gist.github.com/tallpeak/7b8beacc8c273acecb5e
    open System
    
    let inline isNull value = obj.ReferenceEquals(value, null)
    let inline isDBNull value = obj.ReferenceEquals(value, DBNull.Value)
    
    type NullCoalesce =
        static member Coalesce(a: 'a option, b: 'a Lazy) = match a with Some a -> a | _ -> b.Value
        static member Coalesce(a: 'a Nullable, b: 'a Lazy) = if a.HasValue then a.Value else b.Value
        //static member Coalesce(a: 'a when 'a:null, b: 'a Lazy) = match a with null -> b.Value | _ -> a // overridden, so removed
        static member Coalesce(a: DBNull, b: 'b Lazy) = b.Value //added to support DBNull
        // The following line overrides the definition for "'a when 'a:null"
        static member Coalesce(a: obj, b: 'b Lazy) = if isDBNull a || isNull a then b.Value else a // support box DBNull
    let inline nullCoalesceHelper< ^t, ^a, ^b, ^c when (^t or ^a) : (static member Coalesce : ^a * ^b -> ^c)> a b = 
                                                ((^t or ^a) : (static member Coalesce : ^a * ^b -> ^c) (a, b))
    

    Usage:

    let inline (|??) a b = nullCoalesceHelper a b
    let o = box null
    let x = o |?? lazy (box 2)
    let y = (DBNull.Value) |?? lazy (box 3)
    let z = box (DBNull.Value) |?? lazy (box 4)
    let a = None |?? lazy (box 5)
    let b = box None |?? lazy (box 6)
    let c = (Nullable() ) |?? lazy (7)
    let d = box (Nullable() ) |?? lazy (box 8)
    

提交回复
热议问题