我可以接受这个声明:
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#中实现事件?
在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#事件更详细的文档,如果你想了解更多.