Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# F中的配置模式#_F#_Dispose - Fatal编程技术网

F# F中的配置模式#

F# F中的配置模式#,f#,dispose,F#,Dispose,在F#中,继承不如在C#中常见,但这并不意味着它从未被使用过 如果我继承的类型在C#中实现了IDisposable,我通常会使用来抑制终结器。但是,我不能在F#中直接这样做,因为没有受保护的访问修饰符 我在网上搜索了F#中Dispose模式的实现,但只找到了对Dispose()的简单解释。是否有一种模式允许我在派生类中释放非托管资源,同时仍然抑制终结器以优化性能 为了使这个问题稍微不那么抽象,下面是一个我想继承的典型抽象基类型: [<AbstractClass>] type Cont

在F#中,继承不如在C#中常见,但这并不意味着它从未被使用过

如果我继承的类型在C#中实现了
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:说得好!