F# 在外部类型上的Fsharp中实现IEnumerable

F# 在外部类型上的Fsharp中实现IEnumerable,f#,ienumerable,sequence,anonymous-types,F#,Ienumerable,Sequence,Anonymous Types,我试图在没有实现ToEnumerable属性的外部类型上实现它。我无法让代码正常工作 因此,我将其简化为添加一个非类型化的GetEnumerator属性,并添加了用于比较的代码作为指导。但是,我不知道如何为计数器存储可变状态 pb是匿名类吗 你会怎么做 open System open System.Collections open System.Collections.Generic type Bloomberglp.Blpapi.Element with //**WORKS OK

我试图在没有实现ToEnumerable属性的外部类型上实现它。我无法让代码正常工作

因此,我将其简化为添加一个非类型化的GetEnumerator属性,并添加了用于比较的代码作为指导。但是,我不知道如何为计数器存储可变状态

pb是匿名类吗

你会怎么做

open System
open System.Collections
open System.Collections.Generic

type Bloomberglp.Blpapi.Element with
     //**WORKS OK**
     member this.ToComparable:IComparer<Bloomberglp.Blpapi.Element> =   { 
        new IComparer<Bloomberglp.Blpapi.Element> with 
           member this.Compare(x, y) = x.NumValues.CompareTo(y.NumValues) 
     }

     //**WORKS (sort of) OK without storing the state**
     member this.GetEnumerator2:IEnumerator =  {
        //let mutable i =0
        new IEnumerator with
              member this2.Reset() = 
                 i <- 0;
                 ()
              member this2.MoveNext() = 
                 if i < n then 
                    i <- i + 1
                    true
                 else
                    false
              member this2.Current 
                 with get() =
                    this.GetElement(0) :> obj
     }
开放系统
开放系统。集合
open System.Collections.Generic
类型为bloombergglp.Blpapi.Element,带有
//**行吗**
成员this.tocompable:IComparer={
新IComparer与
成员this.Compare(x,y)=x.NumValues.CompareTo(y.NumValues)
}
//**在不存储状态的情况下工作(有点)正常**
此成员。GetEnumerator 2:IEnumerator={
//设可变i=0
新的IEnumerator与
成员this2.Reset()=

i假设
NumValues
是计数,您可以这样做:

type Bloomberglp.Blpapi.Element with
  member this.GetEnumerator() = 
    (Seq.init this.NumValues this.GetElement).GetEnumerator()
type Bloomberglp.Blpapi.Element with
    member this.AsEnumerable =
        seq { for i = 0 to this.NumValues - 1 do
                  yield this.GetElement(i) }

这将返回
IEnumerator假设
NumValues
是计数,您可以执行以下操作:

type Bloomberglp.Blpapi.Element with
  member this.GetEnumerator() = 
    (Seq.init this.NumValues this.GetElement).GetEnumerator()
type Bloomberglp.Blpapi.Element with
    member this.AsEnumerable =
        seq { for i = 0 to this.NumValues - 1 do
                  yield this.GetElement(i) }

这将返回
IEnumerator回到您最初的想法,即在类型中添加一个
ToEnumerable
属性,我可以将该属性命名为AsEnumerable
AsSeq
,因为Seq是IEnumerable的F#术语,并实现如下:

type Bloomberglp.Blpapi.Element with
  member this.GetEnumerator() = 
    (Seq.init this.NumValues this.GetElement).GetEnumerator()
type Bloomberglp.Blpapi.Element with
    member this.AsEnumerable =
        seq { for i = 0 to this.NumValues - 1 do
                  yield this.GetElement(i) }
或者您可以使用
Seq.init
来完成,就像Daniel建议的那样:

type Bloomberglp.Blpapi.Element with
    member this.AsEnumerable =
        Seq.init this.NumValues this.GetElement

回到您最初为类型添加
ToEnumerable
属性的想法,我可能会将属性命名为
AsEnumerable
AsSeq
,因为Seq是IEnumerable的F#术语,并实现如下:

type Bloomberglp.Blpapi.Element with
  member this.GetEnumerator() = 
    (Seq.init this.NumValues this.GetElement).GetEnumerator()
type Bloomberglp.Blpapi.Element with
    member this.AsEnumerable =
        seq { for i = 0 to this.NumValues - 1 do
                  yield this.GetElement(i) }
或者您可以使用
Seq.init
来完成,就像Daniel建议的那样:

type Bloomberglp.Blpapi.Element with
    member this.AsEnumerable =
        Seq.init this.NumValues this.GetElement

的确。好的!我刚开始使用fsharp,很容易错过图片!少了一个状态来跟踪…;)真的。好的!我刚开始使用fsharp,很容易错过图片!少了一个状态来跟踪…;)很好。我想第二个更“实用”因为它(看起来)没有引入任何新的可变状态进行跟踪。我对可变状态的封装使用起来是多么愉快感到惊讶。非常好。我想第二个更“实用”,因为它(似乎)没有引入任何新的可变状态进行跟踪。我对可变状态的封装使用起来是多么愉快感到惊讶。