我试图为一个泛型类型创建各种扩展方法的绑定到特定的泛型类型参数的在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
scroll top