我有一个FileReader
类,其作业是使用StreamReader
来读取和处理文本文件。为了便于进行单元测试,我想给这个类提供一个类型参数,这样我就可以将StreamReader
换成FakeReader
,它实际上并没有与文件系统交互(也许会抛出异常,例如OutOfMemory
,所以我可以测试错误处理在FileReader
)。F#:没有默认构造函数作为类型参数的类?
理想情况下,我想定义FileReader
这样的事情(无足轻重的清晰度):
type FileReader<'Reader> =
member this.Read file =
use sr = new 'Reader(file)
while not sr.EndOfStream do
printfn "%s" <| sr.ReadLine()
,并简单地定义FakeReader
有一个构造函数的文件名,EndOfStream
属性getter的ReadLine()
方法和(空)Dispose()
方法。但是,F#有几个有关此类型定义的投诉,其中包括"Calls to object constructors on type parameters cannot be given arguments."
由于StreamReader
没有默认构造函数,因此此方法看起来像是一个不行。
到目前为止,我已经得到了这个工作的唯一途径是继承FakeReader
从StreamReader
:
type FakeReader() =
inherit StreamReader("") with
override this.ReadLine() = "go away"
member this.EndOfStream = false
member this.Dispose() =()
,并使用返回无论是新FakeReader
或新StreamReader
适当的工厂方法。
type ReaderType = Fake | SR
let readerFactory (file : string, readerType) =
match readerType with
| Fake -> new FakeReader() :> StreamReader
| SR -> new StreamReader(file)
type FileReader(readertype) =
member this.Read file =
use sr = readerFactory(file, readertype)
while not sr.EndOfStream do
printfn "%s" <| sr.ReadLine()
这似乎没那么优雅。有没有办法做到这一点与类型参数?谢谢大家。
你真的希望它基于是OOP或其他任何功能的做法也会为你工作? – Ankur
更实用的方法实际上会很棒。由于在势在必行的土地上多年,我倾向于回到OOP拐杖。 – FSharpN00b