かずきのBlog@hatena

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

購読解除は奥が深い その2

2015/06/23
追記しました

okazuki.hatenablog.com

で書いてた拡張メソッドって要は1つ前のをDisposeすればいいというだけのことだったので以下のような拡張メソッドを準備すればいいのではないかということをひらめいたのでメモ。

public static 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さんに突撃したらこんなリプが。

twitter.com

Switch...なんだって~!

okazuki.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));

あら、綺麗。