かずきのBlog@hatena

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

Reactive Extensions入門 Hello worldその2

1つ前の記事で、IObservableとIObserverを使って簡単なObserverパターンを実装してみました。まだまだ、Reactive Extensionsの便利な機能を使うのには遠く及びません。その上、実装するのは決まった感じのコードを書くため非常にめんどくさいです。


そもそも、Observerパターンって.NETだとイベントとか使えばいいんだから、何で敢えてこの.NET Framework 4の時代になってわざわざ、こんなインターフェースを用意したのか疑問を感じなくも無いですが、これとLINQが組み合わさると凄いことになります。
まぁ、どう凄いかは、そのうちこのBlogで触れるかGoogleでReactive Extensionsで検索すれば色々サンプルが出てくると思います。


さて、気を取り直してReactive Extensionsで提供されている便利なクラスを使って前回のHello worldを書き直してみようと思います。ちょっとだけ便利になります。


まず、IObservableですが汎用的なIObservableの実装として使えるクラスとしてSubjectクラスがあります。こいつはSubscribeも実装してあるし、OnNextメソッドを呼ぶことで変更を通知することができます。ついでに、こいつのSubscribeメソッドのオーバーライドの1つにActionを受け取るものがあります。
このメソッドを使うと、わざわざIObserverを実装しなくても、変更通知に対応したアクションをラムダ式なんかで渡すことができます。


説明が長いのも何なんでさくっとコードを書いてみます。前よりだいぶシンプルにObserverパターンのHello worldが実装出来るようになりました。

namespace RxSample2
{
    using System;
    using System.Collections.Generic;

    class Program
    {
        static void Main(string[] args)
        {
            // IObservable<T>
            var subject = new Subject<string>();

            // IObserverをわざわざ定義しなくてもDelegateでOK
            var d = subject.Subscribe(str => Console.WriteLine(str));

            // subject(Observable)から変更通知
            subject.OnNext("Hello");
            subject.OnNext("World");

            // Subscribeで返されるIDisposableのDisposeを呼ぶと
            // Observableへの登録を解除できる
            d.Dispose();

            // OnNextをしてもWriteLineされない
            subject.OnNext("にゃんこ");
        }
    }
}

実行結果は、以下のようになります。まぁ、Hello worldです。

Hello
World

前回と違うのは、最後のsubject.OnNext("にゃんこ")をしてるのに、コンソールに"にゃんこ"が表示されていないという所です。実はIObservableが実装するSubscribeメソッドが返すIDisposableのDisposeを呼ぶと、Subscribeで追加したものを削除する効果があります。


以上、とっても簡単にObserverパターンが作れるようになってると思います。