Подтвердить что ты не робот

Вызывать метод явного интерфейса базового класса в F #

Ok Вывод типа B из базового класса A. A реализует 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()

конечно, дает a StackOverflowException во время выполнения - так как я могу это сделать? Извините, но никогда не сталкивался с чем-то вроде этого раньше...

4b9b3361

Ответ 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 не работает.

В режиме рефлектора Dispose вызывает только общедоступный метод Close. Таким образом, вы можете повторно реализовать IDisposable и вызвать base.Close().

У вас может быть такой же сценарий на С#. Наследуемые классы, которые реализуют IDisposable, должны обеспечить способ для подклассов "подключаться" к удалению. Обычно это делается путем предоставления перегрузки protected virtual Dispose(disposing), вызванной из Dispose(). По какой-то причине DuplexClientBase не следует этому соглашению. Возможно, это было сочтено ненужным, учитывая, что Dispose просто направляется на Close.

Ответ 2

Вы не можете сделать это с С# или любого языка; явные интерфейсы этого не позволяют.