F# Extension Methods on Lists, IEnumerable, etc

雨燕双飞 提交于 2019-12-25 04:45:32

问题


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.


回答1:


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


来源:https://stackoverflow.com/questions/4579584/f-extension-methods-on-lists-ienumerable-etc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!