活动和代表仪式

Sco*_*rod 0 f#

我可以接受这个声明:

let propertyChanged = 
    Event<PropertyChangedEventHandler,PropertyChangedEventArgs>()
Run Code Online (Sandbox Code Playgroud)

并将其重命名为:

let propertyChangedDelegate = 
    Event<PropertyChangedEventHandler,PropertyChangedEventArgs>()
Run Code Online (Sandbox Code Playgroud)

我想了解F#中的事件宣言仪式.

具体来说,我试图了解之间的区别:

let propertyChanged = 
    Event<PropertyChangedEventHandler,PropertyChangedEventArgs>()
Run Code Online (Sandbox Code Playgroud)

和:

interface INotifyPropertyChanged with
    [<CLIEvent>]
    member this.PropertyChanged = propertyChanged.Publish
Run Code Online (Sandbox Code Playgroud)

这里是整个代码范围:

open System.ComponentModel
open Microsoft.FSharp.Quotations.Patterns

    type ViewModelBase () =
        let propertyChanged = 
            Event<PropertyChangedEventHandler,PropertyChangedEventArgs>()

        let getPropertyName = function 
            | PropertyGet(_,pi,_) -> pi.Name
            | _ -> invalidOp "Expecting property getter expression"

        interface INotifyPropertyChanged with
            [<CLIEvent>]
            member this.PropertyChanged = propertyChanged.Publish

        member private this.NotifyPropertyChanged propertyName = 
            propertyChanged.Trigger(this,PropertyChangedEventArgs(propertyName))

        member this.NotifyPropertyChanged quotation = 
            quotation |> getPropertyName |> this.NotifyPropertyChanged
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释一下如何在F#中实现事件?

Tom*_*cek 5

在F#中,事件只是您可以传递的类型的IEvent<T>.因此,要创建事件,您需要编写此接口的一些实现(处理添加和删除事件处理程序).

Event<T>类型提供了接口的默认合理实现.当你写:

let propertyChanged = 
  Event<PropertyChangedEventHandler,PropertyChangedEventArgs>()
Run Code Online (Sandbox Code Playgroud)

您只是使用F#库中的一个类来创建一个事件的新实现,该事件接受PropertyChangedEventArgs并可以与委托类型的事件处理程序一起使用PropertyChangedEventHandler.

返回的propertyChanged对象有两件事:

  • Publishproperty为您提供IEvent<T>值(表示事件)
  • Trigger方法调用事件(然后调用所有使用IEvent<T>隐藏在propertyChanged对象中的值注册的事件处理程序).

所以写:

interface INotifyPropertyChanged with
    [<CLIEvent>]
    member this.PropertyChanged = propertyChanged.Publish
Run Code Online (Sandbox Code Playgroud)

只是一种暴露事件的方式(使用CLIEvent属性告诉F#编译器它应该被编译为.NET兼容事件).

MSDN上F#事件更详细的文档,如果你想了解更多.