更多F#问题。我在下面有一个二进制阅读器的实现。我希望它像一个可枚举的序列一样工作。下面的代码给我以下错误,我一如既往地没有线索如何解决它。我有一个c#实现,我必须为.Current
属性实现两个不同的覆盖。我想我必须在这里做同样的事,但不知道如何。一如既往,万分感谢您的帮助。
错误FS0366:未对
Collections.IEnumerator.get_Current() : obj
进行实施。请注意,必须在适当的interface
声明下实施并列出所有界面成员,例如interface ... with member ...
。
namespace persisitence
open System.Collections.Generic
open System
open System.IO
type BinaryPersistenceIn<'T>(fn: string, serializer: ('T * BinaryReader) -> unit) as this =
let stream_ = File.Open(fn, FileMode.Open, FileAccess.Read)
let reader_ = new BinaryReader(stream_)
[<DefaultValue>] val mutable current_ : 'T
let eof() =
stream_.Position = stream_.Length
interface IEnumerator<'T> with
member this.MoveNext() =
let mutable ret = eof()
if stream_.CanRead && ret then
serializer(this.current_, reader_)
ret
member this.Current
with get() = this.current_
member this.Dispose() =
stream_.Close()
reader_.Close()
member this.Reset() =
stream_.Seek((int64) 0., SeekOrigin.Begin) |> ignore
答案 0 :(得分:4)
正如@Richard指出的那样,你需要实施IEnumerator.Current
这是响应您的问题“如何做”的代码。这应该有效:
一些注意事项:(感谢@DaxFohl)
IEnumerator
位于不同的命名空间中(请参阅代码)。MoveNext
和Reset
实际上是IEnumerator
的成员,而不是IEnumerator<'t>
的成员,因此这是应该实施的地方。Dispose
但是,IEnumerator<'t>
(惊喜!: - )-
type BinaryPersistenceIn<'T>(fn: string, serializer: ('T * BinaryReader) -> unit) as this =
...
interface IEnumerator<'T> with
...
member this.Current
with get() = this.current_
interface System.Collections.IEnumerator with
member this.Current
with get() = this.current_ :> obj
member this.MoveNext() = ...
member this.Reset() = ...
总而言之,我必须补充一点:你真的确定你想要实施IEnumerator
吗?这是一个相当低调的事情,容易出错。为什么不使用序列计算表达式?
let binaryPersistenceSeq (fn: string) (serializer: BinaryReader -> 'T) =
seq {
use stream_ = File.Open(fn, FileMode.Open, FileAccess.Read)
use reader_ = new BinaryReader(stream_)
let eof() = stream_.Position = stream_.Length
while not eof() do
if stream_.CanRead then
yield serializer reader_
}
答案 1 :(得分:1)
IEnumerator<T>
扩展IEnumerator
,IEnumerator
具有Current
类型的object
属性。
您还需要与IEnumerator<T>.Current
分开实施IEnumerator.Current
。
答案 2 :(得分:0)
这个版本的代码编译......至于它真的有用......会发现。
type BinaryPersistenceIn<'T>(fn: string, serializer: ('T * BinaryReader) -> unit) =
let stream_ = File.Open(fn, FileMode.Open, FileAccess.Read)
let reader_ = new BinaryReader(stream_)
[<DefaultValue>] val mutable current_ : 'T
let eof() =
stream_.Position = stream_.Length
interface IEnumerator<'T> with
member this.MoveNext() =
let mutable ret = eof()
if stream_.CanRead && ret then
serializer(this.current_, reader_)
ret
member this.Current
with get() = this.current_
member this.Dispose() =
stream_.Close()
reader_.Close()
member this.Reset() =
stream_.Seek((int64) 0., SeekOrigin.Begin) |> ignore
member this.Current
with get() = this.current_ :> obj