8

Ich versuche, verschiedene Erweiterungsverfahren für einen generischen Typen auf bestimmten generischen Typparameter in F #, aber die Sprache scheint nicht zu mir erlaubt, gebunden zu erstellen:Erweiterungsmethoden für bestimmte generische Typen

Was ich tun möchte, ist so etwas wie die folgenden:

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

Doch es gibt mir die Compiler-Fehler (Betonung der int Schlüsselwort):

Unerwarteter Bezeichner im Typnamen. Erwarteter Infix-Operator, Anführungszeichen oder anderes Token.

Die folgende hat Arbeit, obwohl es nicht speziell auf die generischen Typparameter zu int nicht bindet, wie ich will:

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

Gibt es eine Möglichkeit, dieses Ziel in F # zu erreichen - bin ich Vielleicht nur mit der falschen Syntax? Wenn nicht, würde ich mich freuen, wenn jemand einen Workaround vorschlagen könnte, vielleicht irgendwo mit type constraints.

Antwort

7

Dies ist nicht möglich, in der aktuellen Version von F #, leider. Siehe verwandte Frage here.

+0

Scheint du bist in der Tat richtig. Danke trotzdem. – Noldorin

+0

Diese Funktion wird von einem Vorschlag in der internen F # -Fehlerdatenbank "4548: Unterstützungserweiterungsmethoden für bestimmte Instantiierungen" verfolgt, es ist jedoch unwahrscheinlich, dass der Schnitt für die VS2010-Version vorgenommen wird. – Brian

0

Nun, Sie können Einschränkungen verwenden - aber nicht mit versiegelten Typen wie Int. Hmm

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

...

+1

Danke für den Vorschlag, aber in der Tat, ich arbeite mit einem versiegelten Typ hier, so dass es nicht ganz funktioniert. – Noldorin

+0

Dies ist wahrscheinlich nicht ganz das, was Sie denken ... Sie definieren tatsächlich einen neuen 'IEnumerable' Typ - versuchen Sie, die Erweiterung auf einem vorhandenen' IEnumerable 'aufzurufen. – kvb

6

Allgemeine Erweiterungsmethoden sind jetzt in 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

Um andere zu helfen, für ähnliche Lösungen suchen, hier ein Beispiel zeigt, wie mit Typ-Constraints generic Erweiterungsmethoden zu verwenden. Im folgenden Beispiel gibt es eine Typbeschränkung, die erfordert, dass das übergebene type-Argument einen Standardkonstruktor verfügbar macht. Dies geschieht mit dem Attribut [<CLIMutable>], das auf den Datensatz Order angewendet wird. Außerdem beschränke ich das Ergebnis der Methode auf den übergebenen Typ.

Um die Erweiterungsmethode zu verwenden, müssen Sie den Typ angeben, den Sie verwenden möchten. Beachten Sie, dass ich auch eine generische Wörterbuchschnittstelle erweitere.

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