2015/06/23 追記しました
購読解除は奥が深い - かずきのBlog@hatenaokazuki.hatenablog.com
で書いてた拡張メソッドって要は1つ前のをDisposeすればいいというだけのことだったので以下のような拡張メソッドを準備すればいいのではないかということをひらめいたのでメモ。
publicstatic IObservable<IDisposable> SerialDispose(this IObservable<IDisposable> self) { var d = new SerialDisposable(); return self.Do(x => d.Disposable = x); }
使い方はこんな感じ。
var vm = new MainWindowViewModel(); vm.Person .Where(x => x != null) .Select(x => x.Name.Subscribe(y => Debug.WriteLine(y))) .SerialDispose() .Subscribe();
追記と綺麗な解決方法
とここまで書いて、ネタ元のyone64さんに突撃したらこんなリプが。
@okazukiちなみに元ネタの方はIO<T>.Select(t => t.RxProp).Switch().Subscribe()みたいな書き方で落ち着いてます。(ブログにフィードバックできてないですが…
— よねやん (@yone64) 2015, 6月 23
twitter.comSwitch...なんだって~!
Reactive Extensions再入門 その40「IObservableの合成はじめました」 - かずきのBlog@hatenaokazuki.hatenablog.com
上記記事によると最後のIOの値を流すとある。今回の例にぴったりじゃないか。ということで最適解はこれっぽいです。
var person = new Person(); var vm = new MainPageViewModel(); vm.Person .Select(x => x == null ? Observable.Never<string>() : x.Name) .Switch() .Subscribe(x => Debug.WriteLine(x));
VS2015だとこう書ける。
vm.Person
.Select(x => x?.Name ?? Observable.Never<string>())
.Switch()
.Subscribe(x => Debug.WriteLine(x));
あら、綺麗。