简体   繁体   中英

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. 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...

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 .

You can't do this from C# or any language; explicit interfaces do not allow this.

Calling base class explicit interface can be done using reflection.
See my answer to a related question about C#:
How to call an explicitly implemented interface-method on the base class

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM