かずきのBlog@hatena

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

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パターンが作れるようになってると思います。