15

わかりBました、基本クラスから型を派生させAます。 明示的にA実装しますが、 で追加のクリーンアップを行う必要があるため、 で実装します。IDisposableBIDisposableB

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

おそらく、クリーンアップ ロジックを仮想メソッドに入れて、1 回だけ実装する方がよいでしょう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それが機能しない理由です。

Reflector を見るDisposeと、パブリックCloseメソッドのみが呼び出されます。したがって、代わりに再実装IDisposableして呼び出すことができますbase.Close()

これと同じシナリオを C# でも使用できます。実装する継承可能なクラスはIDisposable、サブクラスが破棄に「プラグイン」する方法を提供する必要があります。これは通常、protected virtual Dispose(disposing)from から呼び出されるオーバーロードを提供することによって行われ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 に答える