开发者

F# constructor syntax - overiding and augmenting new

I have a non-disposable class with Open/Close syntax that I'd like to be able to use, so I'm trying to inherit from it, and work the Open into the new and the Close into Dispose.

The second part is o开发者_开发技巧k, but I can't work out how to do the Open:

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

(cf. this question which I asked a long time ago, but I can't join the dots to this one)


Key is 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()


As Brian suggests, you can use the as this clause. However, in F#, it is usually recomended to use subclassing (inheritance) only when there is a really good reason for that (e.g. you need to implement some virtual class and pass it to a .NET library).

If I was implementing your example, I would probably prefer function returning IDisposable using a simple object expression:

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"

To some point, this is just a personal preference, but I think it is a preferred option, because it is simpler than using inheritance (although I don't have any document to link here :-)). Also, the compiled code may be a bit simpler, because handling as this may require some runtime checks.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜