列表,IEnumerable等上的F#扩展方法 [英] F# Extension Methods on Lists, IEnumerable, etc

查看:97
本文介绍了列表,IEnumerable等上的F#扩展方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,如果我有一个小部件定义,请说:

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

我想允许轻松打印小部件列表,我可以这样做:

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

我将如何使用记录类型和集合(最好是F#中的List或Seq)来完成类似的工作.我很想拥有Widgest的列表,并且能够在集合上调用执行此功能的函数.假设(因为它是F#)该函数将不会更改其附加到的集合的状态,而是返回一些新值.

解决方案

在F#中不可能有完全类似的解决方案.只能将F#扩展成员定义为原始类型的成员,因此您可以在通用类型IEnumerable<'T>上定义F#扩展,而不能在诸如IEnumerable<Widget>的特定实例上定义.

在C#中,扩展方法通常用于提供更流畅的编码样式(例如myWidgets.PrintAll(tw)).在F#中,通常只需要定义一个让结函数并使用管道运算符即可达到类似的效果.例如:

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

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

这篇关于列表,IEnumerable等上的F#扩展方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆