読者です 読者をやめる 読者になる 読者になる

かずきのBlog@hatena

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

購読解除は奥が深い その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));

あら、綺麗。