かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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)を待ち合わせるがまだ値が取れない

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