F# F中的配置模式#
在F#中,继承不如在C#中常见,但这并不意味着它从未被使用过 如果我继承的类型在C#中实现了F# F中的配置模式#,f#,dispose,F#,Dispose,在F#中,继承不如在C#中常见,但这并不意味着它从未被使用过 如果我继承的类型在C#中实现了IDisposable,我通常会使用来抑制终结器。但是,我不能在F#中直接这样做,因为没有受保护的访问修饰符 我在网上搜索了F#中Dispose模式的实现,但只找到了对Dispose()的简单解释。是否有一种模式允许我在派生类中释放非托管资源,同时仍然抑制终结器以优化性能 为了使这个问题稍微不那么抽象,下面是一个我想继承的典型抽象基类型: [<AbstractClass>] type Cont
IDisposable
,我通常会使用来抑制终结器。但是,我不能在F#中直接这样做,因为没有受保护的访问修饰符
我在网上搜索了F#中Dispose模式的实现,但只找到了对Dispose()
的简单解释。是否有一种模式允许我在派生类中释放非托管资源,同时仍然抑制终结器以优化性能
为了使这个问题稍微不那么抽象,下面是一个我想继承的典型抽象基类型:
[<AbstractClass>]
type ContentPage<'TViewModel, 'TView when 'TViewModel :> ReactiveViewModel and 'TViewModel : not struct>(theme: Theme) as this =
inherit ContentPage()
let messageReceived (message: AlertMessage) = this.DisplayAlert(message.Title, message.Message, message.Accept) |> ignore
let mutable viewModel, listener = Unchecked.defaultof<'TViewModel>, Observable.Never<AlertMessage>().Subscribe(messageReceived)
do base.BackgroundColor <- theme.Styles.BackgroundColor
member __.ViewModel with get() = viewModel and set(value: 'TViewModel) = listener.Dispose(); viewModel <- value; listener <- value.MessageSent.Subscribe(messageReceived)
abstract member CreateContent: unit -> View
interface IViewFor<'TViewModel> with member __.ViewModel with get() = this.ViewModel and set(value) = this.ViewModel <- value
interface IViewFor with member __.ViewModel with get() = (this :> IViewFor<'TViewModel>).ViewModel :> obj and set(value: obj) = (this :> IViewFor<'TViewModel>).ViewModel <- (value :?> 'TViewModel)
interface IDisposable with member __.Dispose() = listener.Dispose()
override __.OnAppearing() =
base.OnAppearing()
match box this.Content with
| null -> this.Content <- this.CreateContent()
| _ -> this |> ignore
[]
键入ContentPage(主题:theme)如下所示=
继承ContentPage()
let messageReceived(message:AlertMessage)=this.DisplayAlert(message.Title,message.message,message.Accept)|>忽略
让可变的viewModel,listener=Unchecked.defaultof).viewModel:>obj并设置(值:obj)=(this:>iviewforthis.Content this |>ignore
如果我要实现C#Dispose模式的F#模拟,那么Dispose()
会是什么样子?您不能直接在F#中实现Dispose
调用链。base.Dispose()
不起作用,因为base
属于ContentPage
类型,并且不会隐式强制转换为IDisposable
base
只允许成员访问,因此您也不能显式强制转换。以下内容不会编译
type BrokenPage() =
inherit ContentPage()
interface IDisposable with
member __.Dispose() =
(base :> IDisposable).Dispose()
为了避免这种情况,需要另一种方法。因为F#中没有受保护的,所以这个习惯用法仍然不是完美的
type ContentPage() =
abstract Close : unit -> unit
default this.Close() =
// cleanup ContentPage here
GC.SuppressFinalize(this)
interface IDisposable with
member this.Dispose() =
this.Close()
type SomePage() =
inherit ContentPage()
override this.Close() =
// cleanup SomePage here
base.Close()
interface IDisposable with
member this.Dispose() =
this.Close()
protected
是该习惯用法中最不重要的方面。相反,将其公开,并着手处理更重要的事情。-]也就是说,只有当您的类型有终结器时,禁止终结才重要,ContentPage
没有,所以在我看来这是一个没有实际意义的点……这肯定会起到作用。:)关于终结器,公平点,但这是一个抽象的基类,我无法控制人们决定如何处理他们的派生类。这似乎没有托管资源,所以您真的需要完整的Dispose模式吗?为什么不让Dispose方法可以重写?@RobLyndon:说得好!