F#でINotifyPropertyChangedを実装するとどうなるかな~というので実装してみた。
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
open Microsoft.FSharp.Quotations.DerivedPatterns
type BindableBase() =
let propertyChnged = Event<_, _>()
interface System.ComponentModel.INotifyPropertyChanged with
[<CLIEventAttribute>]
member x.PropertyChanged = propertyChnged.Publish
member x.Set<'T>((field: 'T byref), value, propertyExpression) =
if (System.Object.Equals(field, value)) then
false
else
field <- value
match propertyExpression with
| PropertyGet(_, info, _) -> propertyChnged.Trigger(x, System.ComponentModel.PropertyChangedEventArgs(info.Name))
| _ -> ()
true
SetメソッドのpropertyExpressionは、F#のコード クォート (F#)を使ってタイプセーフにプロパティ名を指定できるようにしてみました。使い方はこんな感じ。
type Person() =
inherit BindableBase()
let mutable name =""
member this.Name
with get() = name
and set(v) = this.Set(&name, v, <@ this.Name @>) |> ignore
let p = Person() (p :> System.ComponentModel.INotifyPropertyChanged).PropertyChanged.Add(fun e -> printfn "%s" e.PropertyName) p.Name <- "aaa" printfn "%s" p.Name
実行すると
Name aaa
と表示される。