我试图绑定到在F# 特定泛型类型参数的泛型类型创建不同的扩展方法,但语言似乎并没有被允许我:
我想要做的就是像下面这样:
type IEnumerable<int> with
member this.foo =
this.ToString()
然而,它给我的编译器错误(下划线的int
关键字):
意想不到标识符类型名称。 预计管道符,报价符号或其他标记。
下面做工作,尽管它没有特异性结合的泛型类型参数来int
,因为我想:
type IEnumerable<'a> with
member this.foo =
this.ToString()
有什么办法来完成这个目标在F# - 我我也许只是使用了错误的语法? 如果不是这样,我将不胜感激,如果有人能提出一个解决办法,可能使用类型约束地方。
这是不可能在F#的当前版本,很遗憾。 请参阅相关的问题在这里 。
通用扩展方法现在在F#3.1可供选择:
open System.Runtime.CompilerServices
open System.Collections.Generic
[<Extension>]
type Utils () =
[<Extension>]
static member inline Abc(obj: IEnumerable<int>) = obj.ToString()
printfn "%A" ([1..10].Abc())
那么,你可以使用约束 - 但不是与密封类型如int。
type IEnumerable<'a when 'a :> InheritableType> =
member this.Blah =
this.ToString()
嗯...
为了帮助他人寻找类似的解决方案,这里是展示如何使用类型约束泛型扩展方法的例子。 在下面的例子中,有一种类型约束要求参数传递的类型公开一个默认的构造。 这是通过使用完成[<CLIMutable>]
施加到属性Order
记录。 另外,我constraing的方法通过型式的结果。
为了使用扩展方法,你必须指定要使用的类型。 请注意,我还延伸出的通用字典接口。
[<Extension>]
type ExtensionMethds () =
[<Extension>]
static member inline toObject<'T when 'T: (new: unit -> 'T)> (dic: IDictionary<string,obj>): 'T =
let instance = new 'T()
// todo: set properties via reflection using the dictionary passed in
instance
[<CLIMutable>]
type Order = {id: int}
let usage =
let dictionaryWithDataFromDb = dict ["id","1" :> obj]
let theOrder = dictionaryWithDataFromDb.toObject<Order>()
theOrder