вызвать метод явного интерфейса базового класса в F # - PullRequest
12 голосов
/ 05 марта 2012

Хорошо, я извлекаю тип 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()

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

Ответы [ 3 ]

9 голосов
/ 05 марта 2012

Вам, вероятно, лучше поместить свою логику очистки в виртуальный метод и реализовать 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), которая вызывается из Dispose(). По какой-то причине DuplexClientBase не следует этому соглашению. Возможно, это было сочтено ненужным, учитывая, что Dispose просто переходит к Close.

5 голосов
/ 05 марта 2012

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

0 голосов
/ 20 августа 2012

Вызов явного интерфейса базового класса может быть выполнен с использованием отражения.
См. Мой ответ на связанный вопрос о C #:
Как вызвать явно реализованный интерфейсный метод для базового класса

...