سؤال

In C#, if I had a widget definition, say:

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

and I wanted to allow for easy printing of a list of Widgets, I might do this:

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

How would I accomplish something similar with a record type and a collection (List or Seq preferrably in F#). I'd love to have a list of Widgest and be able to call a function right on the collection that did something like this. Assume (since it's F#) that the function would not be changing the state of the collection that it's attached to, but returning some new value.

هل كانت مفيدة؟

المحلول

An exactly analogous solution isn't possible in F#. F# extension members can only be defined as if they were members on the original type, so you can define F# extensions on the generic type IEnumerable<'T>, but not on a specific instantiations such as IEnumerable<Widget>.

In C#, extension methods are often used to provide a more fluent coding style (e.g. myWidgets.PrintAll(tw)). In F#, you'd typically just define a let-bound function and use the pipeline operator to achieve a similar effect. For example:

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top