Синтаксис конструктора F# — переопределение и дополнение новых

У меня есть одноразовый класс с синтаксисом Open/Close, который я хотел бы иметь use, поэтому я пытаюсь наследовать от него и работать с Open в new и Close в Dispose.

Вторая часть в порядке, но я не могу понять, как сделать Open:

type DisposableOpenCloseClass(openargs) =
    inherit OpenCloseClass()
    //do this.Open(openargs)  <-- compiler no like
    interface IDisposable
        with member this.Dispose() = this.Close()

(ср. этот вопрос, который я задал давным-давно , но я не могу поставить точку в этом)


person Benjol    schedule 10.06.2010    source источник


Ответы (2)


Ключ as this:

type OpenCloseClass() =
    member this.Open(x) = printfn "opened %d" x
    member this.Close() = printfn "closed"

open System

type DisposableOpenCloseClass(openargs) as this = 
    inherit OpenCloseClass() 
    do this.Open(openargs)
    interface IDisposable 
        with member this.Dispose() = this.Close() 

let f() =
    use docc = new DisposableOpenCloseClass(42)
    printfn "inside"

f()
person Brian    schedule 10.06.2010

Как предлагает Брайан, вы можете использовать предложение as this. Однако в F# обычно рекомендуется использовать подклассы (наследование) только тогда, когда для этого есть действительно веская причина (например, вам нужно реализовать какой-то виртуальный класс и передать его в библиотеку .NET).

Если бы я реализовывал ваш пример, я бы предпочел функцию, возвращающую IDisposable, используя простое выражение объекта:

let disposableOpenClose(openargs) = 
  let oc = new OpenCloseClass() 
  oc.Open(openargs)  
  { new IDisposable with
      member this.Dispose() = oc.Close() }

let f() =
  use docc = disposableOpenClose(42)
  printfn "inside"

В какой-то момент это просто личное предпочтение, но я думаю, что это предпочтительный вариант, потому что это проще, чем использование наследования (хотя у меня нет никакого документа, на который можно было бы ссылаться здесь :-)). Кроме того, скомпилированный код может быть немного проще, поскольку обработка as this может потребовать некоторых проверок во время выполнения.

person Tomas Petricek    schedule 10.06.2010
comment
Спасибо, в моем конкретном случае мне нужен был доступ к другим функциям в «базовом» классе, поэтому просто вернуть интерфейс было бы недостаточно. - person Benjol; 11.06.2010