Вопрос

Я пытаюсь создать различные методы расширения для общего типа. привязан к конкретным параметрам универсального типа в 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 записывать.Кроме того, я ограничиваю результат метода переданным типом.

Чтобы использовать метод расширения, вам необходимо указать тип, который вы хотите использовать.Обратите внимание, что я также расширяю общий интерфейс словаря.

[<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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top