泥庭

2014年7月1日

ReactivePropertyを使いたい人のための、ReactiveExtensions入門(その3)

Filed under: .NET, LINQ, WPF — タグ: , , , — yone64 @ 10:21 PM

以前のバージョンは → 第1回第2回
サブタイトルをつけておけばよかったなと思いつつ、適当なサブタイトルが思いつかないので今回もそのまま行きます。

さて、MVVM方式(?)でアプリケーションを作成していると、ViewModelが親子構造になることはよくあります。
で、その場合に親ViewModelが子ViewModelのProperty変更を監視したいということも少なからずあります。
ちなみに、非ReactivePropertyな世界だと、PropertyのSetterにイベントの着脱を仕込むのが一般的なのではないでしょうか(と勝手に思ってます)。

private SubContentViewModel _subContent;
public SubContentViewModel SubContent
{
    get
    {
        return _subContent;
    }
    set
    {
        if (_subContent == value) return;
        if (_subContent != null) _subContent.PropertyChanged -= PropertyChanged;
        _subContent = value;
        if (_subContent != null) _subContent.PropertyChanged += PropertyChanged;
    }
}

これを、ReactivePropertyを利用して実現してみます。何も考えないと以下のようにSelectManyで簡単に実現できるように思えます。
# SubContentとTextはそれぞれReactivePropertyです。

this.SubContent
    .Where(s => s != null)
    .SelectMany(s => s.Text)
    .Subscribe(t => Console.WriteLine(t));

しかし、これだと一度購読を開始したSubContentがいつまでたっても解放されないため、メモリリークなどの原因になってしまいます。
これを以下のように記述することで、親ViewModelから参照されなくなった子ViewModelの変更購読を解放することができるようになります。

this.SubContent
    .Select(s => s == null ? null : s.Text.Subscribe(t => Console.WriteLine(t)))
    .Scan(new Tuple<IDisposable, IDisposable>(null, null), (a, b) => Tuple.Create(a.Item2, b))
    .Subscribe(t => { if (t.Item1 != null) t.Item1.Dispose(); });

長いな…

広告

2件のコメント »

  1. […] 以前のバージョンは→第1回、第2回、第3回 […]

    ピンバック by ReactivePropertyを使いたい人のための、ReactiveExtensions入門(その4) | 泥庭 — 2014年7月27日 @ 11:45 AM

  2. 上記記事における内容については、ReactiveProperty作者の@okazukiさんのブログを参照ください。

    http://okazuki.hatenablog.com/entry/2015/06/23/172116

    コメント by yone64 — 2015年6月23日 @ 9:57 PM


RSS feed for comments on this post. TrackBack URI

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

WordPress.com で無料サイトやブログを作成.

%d人のブロガーが「いいね」をつけました。