具体的泛型类型的扩展方法(Extension methods for specific generi

2019-08-17 10:20发布

我试图绑定到在F# 特定泛型类型参数的泛型类型创建不同的扩展方法,但语言似乎并没有被允许我:

我想要做的就是像下面这样:

type IEnumerable<int> with
    member this.foo =
        this.ToString()

然而,它给我的编译器错误(下划线的int关键字):

意想不到标识符类型名称。 预计管道符,报价符号或其他标记。

下面工作,尽管它没有特异性结合的泛型类型参数来int ,因为我想:

type IEnumerable<'a> with
    member this.foo =
        this.ToString()

有什么办法来完成这个目标在F# - 我我也许只是使用了错误的语法? 如果不是这样,我将不胜感激,如果有人能提出一个解决办法,可能使用类型约束地方。

Answer 1:

这是不可能在F#的当前版本,很遗憾。 请参阅相关的问题在这里 。



Answer 2:

通用扩展方法现在在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())


Answer 3:

那么,你可以使用约束 - 但不是与密封类型如int。

type IEnumerable<'a when 'a :> InheritableType> =
member this.Blah =
    this.ToString()

嗯...



Answer 4:

为了帮助他人寻找类似的解决方案,这里是展示如何使用类型约束泛型扩展方法的例子。 在下面的例子中,有一种类型约束要求参数传递的类型公开一个默认的构造。 这是通过使用完成[<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


文章来源: Extension methods for specific generic types