在F#中调用基类显式接口方法

Car*_*ten 13 inheritance f# explicit-interface

好的,我B从基类派生出一个类型A. A实现IDisposable显式但我必须进行额外的清理B,所以我实现IDisposableB:

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

问题是:如何从base访问Dispose-method?

(base :> IDisposable).Dispose()
Run Code Online (Sandbox Code Playgroud)

产生编译错误: Unexpected symbol ':>' in expression. Expected '.' or other token.

做点什么

(i :> IDisposable).Dispose()
Run Code Online (Sandbox Code Playgroud)

当然会产生一个StackOverflowException运行时 - 所以我该怎么做呢?对不起,但从未遇到过这样的事情...

Dan*_*iel 10

您可能最好将清理逻辑放在虚拟方法中并且IDisposable只执行一次.

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()
Run Code Online (Sandbox Code Playgroud)

由于没有protected访问修饰符,您可以使用签名文件进行Close非公开(或标记internal).

base关键字只能用于成员访问,而不能用于独立.这就是为什么base :> IDisposable不起作用.

查看Reflector,Dispose只调用public Close方法.所以你可以重新实现IDisposable并调用base.Close().

您可以在C#中使用相同的方案.实现的可继承类IDisposable应该为子类"插入"处理提供一种方法.这通常通过提供protected virtual Dispose(disposing)从中调用的重载来完成Dispose().无论出于何种原因,DuplexClientBase都不遵循这一惯例.也许Dispose仅仅因为转发而被认为是不必要的Close.


Bri*_*ian 5

你不能用C#或任何语言做到这一点; 显式接口不允许这样做.