Question

Je suis d'essayer de créer différentes méthode d'extension pour un type générique lié à certains paramètres de type générique en F#, mais la langue ne semble pas être de me permettre:

Ce que je veux faire, c'est quelque chose comme ce qui suit:

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

Pourtant, il me donne l'erreur du compilateur (en soulignant l' int le mot-clé):

Inattendu identificateur de type de nom.Attendu opérateur infixe, devis symbole ou un autre jeton.

La suite n' travail, s'il ne doit pas se lier spécifiquement le paramètre de type générique pour int, comme je veux:

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

Est-il possible d'atteindre cet objectif dans F# je suis peut-être juste l'utilisation de la mauvaise syntaxe?Si non, je vous serais reconnaissant si quelqu'un pourrait proposer une solution de contournement, peut-être à l'aide de contraintes de type quelque part.

Était-ce utile?

La solution

Ce n'est pas possible dans la version actuelle de F#, malheureusement.Voir la question relative à la ici.

Autres conseils

Générique des méthodes d'extension sont maintenant disponibles en 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())

Eh bien, vous pouvez utiliser les contraintes, mais pas avec les scellés de type int.

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

Hmm...

Afin d'aider les autres à la recherche pour des solutions similaires, voici un exemple montrant comment utiliser générique des méthodes d'extension avec des contraintes de type.Dans l'exemple ci-dessous, il y a une contrainte de type exigeant que le type de l'argument passé expose un constructeur par défaut.Ceci est fait en utilisant l' [<CLIMutable>] attribut appliqué à la Order record.Aussi, je suis constraing le résultat de la méthode pour le type passé.

Afin d'utiliser la méthode d'extension, vous devez spécifier le type que vous souhaitez utiliser.A noter que je suis aussi en train d'étendre un dictionnaire générique de l'interface.

[<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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top