かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

MVVMのVMをF#で実装するとしたら?

こんな基本クラスを用意しておくと記述が楽かも。まぁ同じことはC#でも言えますが。
ネタ元は以下の記事です。

open System
open System.ComponentModel

/// INotifyPropertyChangedの実装
type NotifyObject() =
    let propertyChangedEvent = Event<_, _>()
	
    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChangedEvent.Publish
	
    /// プロパティのsetterの実装簡略化用メソッド
    member x.SetProperty((field : 'a byref), (value : 'a), (name : string)) =
        if field = value then
            ()
        else
            field <- value
            propertyChangedEvent.Trigger(x, PropertyChangedEventArgs(name))

/// お試し実装
type HogeViewModel() =
    inherit NotifyObject()
    
    let mutable name = "default value"
    
    member x.Name
        with get() = name
        and set v = x.SetProperty(&name, v, "Name")

// 使ってみる
let vm = HogeViewModel()

// PropertyChangedがちゃんと動いてるか確認用イベントハンドラを登録
let p = vm :> INotifyPropertyChanged
p.PropertyChanged.Add <| fun e -> (printfn "%s property changed" e.PropertyName)

// レッツ代入
vm.Name <- "田中"
printfn "name = %s" vm.Name
vm.Name <- "Tanaka"
printfn "name = %s" vm.Name

実行すると、以下のような結果になります。ちゃんと動いてるくさい。

Name property changed
name = 田中
Name property changed
name = Tanaka

プロパティ名を文字列で指定してるところを、タイプセーフに指定できるようにすればOKだ。F#だと<@ ... @>みたいに書くんだったかな。後で調べよう。