好的,我从基类B
派生出一个A
类型。
A
明确实现IDisposable
,但我必须在B
中进行额外清理,因此我在IDisposable
中实施B
:
interface IDisposable with
member i.Dispose() =
// ... additional work
base.Dispose() // <- want to do but cannot
问题是:如何从base访问Dispose-method?
(base :> IDisposable).Dispose()
产生编译器错误:Unexpected symbol ':>' in expression. Expected '.' or other token.
做类似
的事情(i :> IDisposable).Dispose()
当然在运行时产生StackOverflowException
- 所以我该怎么做呢?对不起,但从未遇到过类似的事情......
答案 0 :(得分:9)
您可能最好将清理逻辑放在虚拟方法中并仅实施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
的可继承类应该为子类提供一种方法来插入&#34;插入&#34;处置。这通常是通过提供从protected virtual Dispose(disposing)
调用的Dispose()
重载来完成的。无论出于何种原因,DuplexClientBase
都不遵循此约定。鉴于Dispose
只是转发到Close
,可能认为没有必要。
答案 1 :(得分:5)
你不能用C#或任何语言做到这一点;显式接口不允许这样做。
答案 2 :(得分:0)
可以使用反射来调用基类显式接口。
请参阅我对C#相关问题的回答:
How to call an explicitly implemented interface-method on the base class