У меня есть одноразовый класс с синтаксисом 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()
(ср. этот вопрос, который я задал давным-давно , но я не могу поставить точку в этом)
Ответ 1 · рейтинг 10 · Brian
Ключ 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()
Ответ 2 · рейтинг 4 · Tomas Petricek
Как предлагает Брайан, вы можете использовать предложение 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 может потребовать некоторых проверок во время выполнения.