为支持null的结构和引用类型键入约束

时间:2012-08-06 22:21:13

标签: generics f# constraints

是否可以将类型约束为支持null的结构或引用类型?类似于此函数的假设约束:

let getOrDefault<'T when ('T : struct) or ('T : null)> (d: IDictionary<_, 'T>) key =
  match d.TryGetValue(key) with
  | true, v -> v
  | _ -> Unchecked.defaultof<'T>

该功能不应与F#类型一起使用,除非标有[<AllowNullLiteral>]

1 个答案:

答案 0 :(得分:3)

我认为你不能在{2}之间放置or。 通常当我需要像constraint1或constraint2或...或constraintN这样的东西时,我会创建重载:

open System.Collections.Generic

// unconstrained function
let getOrDefaultG (d: IDictionary< _ , 'T>) key =
  match d.TryGetValue(key) with
  | true, v -> v
  | _ -> Unchecked.defaultof<'T>

// individually constrained
let getOrDefaultS<'K,'T when 'T :struct> (d:IDictionary<'K,'T>) = getOrDefaultG d
let getOrDefaultN<'K,'T when 'T :null  > (d:IDictionary<'K,'T>) = getOrDefaultG d

// overloads
type GetOrDefault = GetOrDefault with
    static member ($) (GetOrDefault, d) = fun dummyArg        -> getOrDefaultS d
    static member ($) (GetOrDefault, d) = fun (dummyArg:unit) -> getOrDefaultN d

// the desired function
let inline getOrDefault d key = (GetOrDefault $ d) () key

注意:dummyArg是我用来创建两个不同签名并使其编译的技巧。