更多 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
正如@Richard 指出的,你需要实现IEnumerator.Current
.
这是回答您的问题“如何做”的代码。这应该有效:
一些注释:(感谢@DaxFohl)
-
IEnumerator
位于不同的命名空间中(参见代码)。
-
MoveNext
and Reset
确实是以下成员IEnumerator
, not 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() = ...
最后,我必须补充一点:你真的吗?sure你想实施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_
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)