我不認爲你可以把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是一招我用它來創建兩個不同的簽名,並把它編譯。
如果你有兩個以上的重載,你將如何處理'dummyArg'? – Daniel 2012-08-07 22:00:33
好問題!我會添加另一個名爲dummyArg2的參數,然後在第一次重載時,我將根本不會輸入任何類型,僅次於dummyArg1,而第三次輸入兩者。我不明白爲什麼我必須做這些技巧。簽名不同(錯誤?)。 – Gustavo 2012-08-07 23:17:51