かずきのBlog@hatena

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

Reactive Extensions入門 1 Hello world

Reactive Extensionsって色々小難しくIEnumerableの数学的に反対に位置するのがIObservableだって言われたりしてますが、とりあえずObserverパターンってやつです。


なので、一番シンプルなReactive ExtensionsのHello worldをやると、単純なObserverパターンになります。ここで肝になるインターフェースは2つです。
IObservableとIObserverです。どちらもObserverパターンに出てくる基本的な名前なので説明はいらないと思います。

気になる人は、GoogleでObserverパターンでぐぐるといいと思います。


では早速IObservableの実装をしてみます。

internal class MyObservable : IObservable<string>
{
    private ICollection<IObserver<string>> collection = new List<IObserver<string>>();

    #region IObservable<int> メンバー
    public IDisposable Subscribe(IObserver<string> observer)
    {
        collection.Add(observer);
        // 一度追加したObserverの削除には対応しない
        return null;
    }
    #endregion

    // 自分をSubscribeしてるObserverに変更を通知する
    public void Notify(string value)
    {
        foreach (var observer in collection)
        {
            observer.OnNext(value);
        }
    }
}

特に難しいことはしていません。SubscribeメソッドでObserverを追加してNotifyで、追加されたObserverに対して変更通知を行っています。
次に、このMyObservableを監視するMyObserverを作成します。

internal class MyObserver : IObserver<string>
{
    // とりあえず無視
    public void OnCompleted()
    {
        throw new NotImplementedException();
    }

    // とりあえず無視
    public void OnError(Exception error)
    {
        throw new NotImplementedException();
    }

    // 変更通知を受け取るメソッド
    public void OnNext(string value)
    {
        // とりあえず表示する
        Console.WriteLine("OnNext: " + value);
    }
}

これで、完成です。OnCompletedメソッドとOnErrorメソッドは今回は使わないので実装はしてません。


最後に、これを使うMainメソッドを書きます。

class Program
{
    static void Main(string[] args)
    {
        var ob = new MyObservable();
        ob.Subscribe(new MyObserver());

        ob.Notify("Hello");
        ob.Notify("World");
    }
}

Observableを作成してObserverを追加して、変更通知をしてるだけのシンプルな実装です。実行すると、以下のような結果が得られます。

OnNext: Hello
OnNext: World

非常に単純ですが、このObservableとObserverを変態的に拡張しまくったのがReactive Extensionsです。とりあえずHello worldはこんな感じです。
まだ簡単ですね。