かずきのBlog@hatena

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

ReactivePropertyで値が変更されたタイミングで前の値と新しい値を取得する

先日TLを眺めてた時にid:neueccさんがコードをぺちぺちと貼ってたのを見て感動したのでメモっておきます。

var p = new ReactiveProperty<int>(1, mode: ReactivePropertyMode.RaiseLatestValueOnSubscribe);

p.Zip(p.Skip(1), (x, y) => new { OldValue = x, NewValue = y })
    .Subscribe(t =>
        Console.WriteLine("old: {0}, new: {1}", t.OldValue, t.NewValue));

p.Value = 10;
p.Value = 100;

実行結果

old: 1, new: 10
old: 10, new: 100

ちゃんと取れるんですね・・・。Zipで自分自身の1つ先の値を待ち合わせることで古い値と新しい値をとるなんて・・・。頭やわらかい。多分こんな流のはず。

  1. 初期値1がOnNextに渡る
    1. Zipでp.Skip(1)を待ち合わせるがまだ値が取れない
  2. p.Value = 10でSkip(1)で待ってた所に待望の値が来る
    1. xに1, yに10が入るので匿名型でまとめる
    2. Subscribeで処理を行う(ここでは標準出力に出力)
  3. 10が代入されたため、新たな値がOnNextされる
    1. ZipでSkip(1)を待ち合わせるがまだ値が取れない
  4. p.Value = 100でSkip(1)で待ってた所に待望の値が来る
    1. xに1, yに100が入るので匿名型でまとめる
    2. Subscribeで処理を行う(ここでは標準出力に出力)
  5. 100が代入されたため、新たな値がOnNextされる
    1. ZipでSkip(1)を待ち合わせるがまだ値が取れない

多分、上記のようなことが起きてるのだと思います・・・。う〜ん奥が深い。