15

好的,我B从基类派生一个类型AA实现IDisposable显式,但我必须在 中进行额外的清理B,所以我IDisposable在 中实现B

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

问题是:如何从基础访问 Dispose 方法?

(base :> IDisposable).Dispose()

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

做类似的事情

(i :> IDisposable).Dispose()

当然StackOverflowException会在运行时产生 - 那么我该怎么做呢?抱歉,以前从来没有遇到过这样的事情……

4

3 回答 3

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

由于没有protected访问修饰符,您可以使用签名文件将其设为Close非公开(或标记internal)。

base关键字只能用于会员访问,不能单独使用。这就是为什么base :> IDisposable不起作用。

查看反射器,Dispose只调用公共Close方法。所以你可以重新实现IDisposable并调用base.Close()

您可以在 C# 中拥有相同的场景。实现的可继承类IDisposable应该为子类“插入”处理提供一种方式。这通常是通过提供protected virtual Dispose(disposing)从 调用的重载来完成的Dispose()。无论出于何种原因,DuplexClientBase不遵循此约定。鉴于Dispose仅转发到,也许它被认为是不必要的Close

于 2012-03-05T15:10:54.477 回答
5

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

于 2012-03-05T19:17:01.537 回答
0

可以使用反射来调用基类显式接口。
请参阅我对有关 C# 的相关问题的回答:
如何在基类上调用显式实现的接口方法

于 2012-08-20T19:44:47.273 回答