10
votes

Méthodes d'extension pour types génériques spécifiques

Je tente de créer diverses méthodes d'extension pour un type générique lié ​​à des paramètres de type générique spécifiques em> dans F #, mais la langue ne semble pas me permettre:

Ce que je veux Faites quelque chose comme ce qui suit: p> xxx pré>

Pourtant, cela me donne l'erreur du compilateur (soulignant le mot-clé int code> p>

identifiant inattendu dans le nom de type. Opérateur d'infixe attendu, symbole de devis ou autre jeton. P> blockQquote>

Les em> les em> sont em>, bien qu'il ne lie pas spécifiquement le paramètre de type générique sur int code>, tel que je veux: p>

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


0 commentaires

4 Réponses :


0
votes

Eh bien, vous pouvez utiliser des contraintes - mais pas avec des types scellés tels que INT.

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


2 commentaires

Merci pour la suggestion, mais en effet, je travaille avec un type scellé ici, donc cela ne fonctionne pas bien.


Cela ne fait probablement pas vraiment ce que vous pensez ... Vous définissez réellement un nouveau iEnumerable Type - essayez d'appeler l'extension sur un iEnumerable existant .



8
votes

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


1 commentaires

Cette fonctionnalité est suivie par une suggestion dans la base de données de bugs F # interne "4548: Méthodes d'extension de support pour des instanciations de type spécifiques", mais il est peu probable que la coupe de la version VS2010.



9
votes

Les méthodes d'extension génériques 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())


0 commentaires

0
votes

Pour aider les autres à rechercher des solutions similaires, voici un exemple indiquant comment utiliser des méthodes d'extension génériques avec des contraintes de type. Dans l'exemple ci-dessous, il existe une contrainte de type qui oblige l'argument de type transmis expose un constructeur par défaut. Ceci est fait à l'aide de l'attribut [] code> appliqué à l'enregistrement code> code>. De plus, je construit le résultat de la méthode du type passé.

Pour utiliser la méthode d'extension, vous devez spécifier le type que vous souhaitez utiliser. Notez que j'extuit également une interface de dictionnaire générique. P>

[<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


0 commentaires