Search code examples
inheritancef#explicit-interface

call a base-class explicit interface method in F#


Ok I derive a type B from a base class A. A implements IDisposable explicit but I have to do additional cleanup in B, so I implement IDisposable in B:

interface IDisposable with
    member i.Dispose() =
        // ... additional work
        base.Dispose() // <- want to do but cannot

Question is: how to access the Dispose-method from base?

(base :> IDisposable).Dispose()

yields compiler error: Unexpected symbol ':>' in expression. Expected '.' or other token.

Doing something like

(i :> IDisposable).Dispose()

of course yields a StackOverflowException on runtime - so how can I do this? Sorry but never encountered something like this before...


Solution

  • You're probably better off putting your clean-up logic in a virtual method and implementing IDisposable only once.

    type A() =
      abstract Close : unit -> unit
      default __.Close() =
        printfn "Cleaning up A"
      interface System.IDisposable with
        member this.Dispose() = this.Close()
    
    type B() =
      inherit A()
      override __.Close() = 
        printfn "Cleaning up B"
        base.Close()
    

    Since there's no protected access modifier, you can use a signature file to make Close non-public (or mark it internal).

    The base keyword can only be used for member access, not standalone. That's why base :> IDisposable doesn't work.

    Looking in Reflector, Dispose only calls the public Close method. So you could re-implement IDisposable and call base.Close() instead.

    You could have this same scenario in C#. Inheritable classes that implement IDisposable should provide a way for subclasses to "plug in" to disposal. This is usually done by providing a protected virtual Dispose(disposing) overload that's called from Dispose(). For whatever reason, DuplexClientBase doesn't follow this convention. Perhaps it was deemed unnecessary given that Dispose merely forwards to Close.