2011-01-02 8 views
0

Ich habe Stackoverflow (und andere Quellen) gesucht für diese Antwort, aber kann nicht scheinen, nichts zu finden.F # Extention Methoden auf Listen, IEnumberable, etc

In C#, wenn ich eine Widget Definition habe, sagen:

class widget 
{ 
    public string PrettyName() { ... do stuff here } 
} 

und ich wollte für einfaches Drucken einer Liste von Widgets ermöglichen, könnte ich dies tun:

namespace ExtensionMethods 
{ 
    public static PrintAll(this IEnumerable<Widget> widgets, TextWriter writer) 
    { 
     foreach(var w in widgets) { writer.WriteLine(w.PrettyName()) } 
    } 
} 

Wie würde ich etwas Ähnliches mit einem Datensatztyp und einer Sammlung erreichen (List oder Seq vorzugsweise in F #). Ich würde gerne eine Liste von Widgest haben und in der Lage, eine Funktion direkt an der Sammlung zu nennen, die so etwas wie dies taten. Es sei angenommen, (da es F #), dass die Funktion nicht den Zustand der Sammlung sich ändern würde, dass es angebracht ist, aber einige neue Wert zurück.

Antwort

4

Eine genau analoge Lösung ist in F # nicht möglich. F # -Erweiterungsmember können nur so definiert werden, als wären sie Mitglieder des ursprünglichen Typs. Sie können also F # -Erweiterungen für den generischen Typ IEnumerable<'T> definieren, nicht jedoch für bestimmte Instanzen wie IEnumerable<Widget>.

In C#, sind Erweiterungsmethoden oft einen flüssigeren Codierstil (z.B. myWidgets.PrintAll(tw)) bereitzustellen, verwendet. In F # würden Sie normalerweise nur eine gebundene Funktion definieren und den Pipelineoperator verwenden, um einen ähnlichen Effekt zu erzielen. Zum Beispiel:

module Widget = 
    let printAll (tw:TextWriter) s = 
    for (w:Widget) in s do 
     writer.WriteLine(w.PrettyName()) 

open Widget 
let widgets = // generate a sequence of widgets somehow 
let tw = TextWriter() 
widgets |> printAll tw 
+0

Wie würde ich die Funktion printAll als Mitglied im Widget Datensatztyp für die Verwendung in dem obigen Szenario definieren? – fbl

+0

@ flevine100 - Sie würden normalerweise _not_ definieren printAll als Mitglied an einem Typ, sondern als let gebundene Funktion in einem Modul. Ich habe meine Antwort so bearbeitet, dass sie ein Beispiel enthält. – kvb

+0

danke! - Functional Programming ist definitiv eine andere Art zu denken über Code-Organisation. – fbl

Verwandte Themen