F# 在外部类型上的Fsharp中实现IEnumerable
我试图在没有实现ToEnumerable属性的外部类型上实现它。我无法让代码正常工作 因此,我将其简化为添加一个非类型化的GetEnumerator属性,并添加了用于比较的代码作为指导。但是,我不知道如何为计数器存储可变状态 pb是匿名类吗 你会怎么做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
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,很容易错过图片!少了一个状态来跟踪…;)很好。我想第二个更“实用”因为它(看起来)没有引入任何新的可变状态进行跟踪。我对可变状态的封装使用起来是多么愉快感到惊讶。非常好。我想第二个更“实用”,因为它(似乎)没有引入任何新的可变状态进行跟踪。我对可变状态的封装使用起来是多么愉快感到惊讶。