我有一個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