2010-06-10 20 views
7

我有一個非一次性的類,打開/關閉語法,我想能夠use,所以我試圖從它繼承,並將Open打入new和關閉處置。F#的構造函數語法 - overiding和augmenting新的

第二部分是確定的,但我不能工作,如何做好開放:

type DisposableOpenCloseClass(openargs) = 
    inherit OpenCloseClass() 
    //do this.Open(openargs) <-- compiler no like 
    interface IDisposable 
     with member this.Dispose() = this.Close() 

(參見this question我問了很久以前,但我不能加入點這一個)

回答

10

主要是as this

type OpenCloseClass() = 
    member this.Open(x) = printfn "opened %d" x 
    member this.Close() = printfn "closed" 

open System 

type DisposableOpenCloseClass(openargs) as this = 
    inherit OpenCloseClass() 
    do this.Open(openargs) 
    interface IDisposable 
     with member this.Dispose() = this.Close() 

let f() = 
    use docc = new DisposableOpenCloseClass(42) 
    printfn "inside" 

f() 
4

布賴恩建議,您可以使用as this條款。但是,在F#中,只有在確實有充分的理由時(例如,您需要實現一些虛擬類並將其傳遞給.NET庫),通常才推薦使用子類化(繼承)。

如果我實現你的榜樣,我可能會更喜歡功能使用簡單對象表達返回IDisposable

let disposableOpenClose(openargs) = 
    let oc = new OpenCloseClass() 
    oc.Open(openargs) 
    { new IDisposable with 
     member this.Dispose() = oc.Close() } 

let f() = 
    use docc = disposableOpenClose(42) 
    printfn "inside" 

爲了某些時候,這僅僅是個人喜好,但我認爲這是一個因爲它比使用繼承簡單(儘管我沒有任何文檔可以鏈接到這裏:-))。此外,編譯的代碼可能會更簡單一些,因爲處理as this可能需要一些運行時檢查。

+0

謝謝,在我的特殊情況下,我需要訪問'base'類中的其他函數,所以僅僅返回接口是不夠的。 – Benjol 2010-06-11 05:31:33