入門するのは私なんですけどね。.NET Framework 4 SP1 で追加されると噂の Reactive Extensions(以下 Rx)。ずっと気にはなっていたんですが、まったく触っていませんでした。
id:okazuki さんが Rx の入門記事を書いていたり、neue さんが Rx の詳細な解説を書いていたりしていて、今更な感じがしますが、ブログのネタに困っていたので記事にしてみます。車輪の再発明みたいなもんです。あと、コード書かないと理解できない残念な頭なので、記憶の整理も兼ねています。
Rx と言えば、仮面ライダー…じゃなかった、Observer パターンです。あの GoF のデザインパターンのひとつ。
簡単に言えば Rx は「Observer パターンを実装し、さらに変態的に拡張しまくったライブラリ」ってところです。
Rx の中心に、IObserver
using System; using System.Collections.Generic; namespace RxSample1 { partial class Program { static void Main(string[] args) { // 通知を出すオブジェクト var ob = new FooObservable(); // 通知先のオブジェクトと登録 ob.Subscribe(new FooObserver()); // 通知を出す ob.Notify("Hello"); ob.Notify("World"); Console.ReadLine(); } } // 通知を出すクラス public class FooObservable : IObservable<string> { // 通知先のオブジェクトを格納 private List<IObserver<string>> _observers = new List<IObserver<string>>(); // 通知先のオブジェクトを登録 public IDisposable Subscribe(IObserver<string> observer) { _observers.Add(observer); return null; } // 登録されているオブジェクトに通知を出す public void Notify(string value) { foreach (var o in _observers) { o.OnNext(value); } } } // 通知を受けるクラス public class FooObserver : IObserver<string> { public void OnCompleted() { } public void OnError(Exception error) { } // 通知を受けて何かする public void OnNext(string value) { Console.WriteLine("FooObserver: {0}", value); } } }
IObservable
using System; using System.Collections.Generic; namespace RxSample2 { partial class Program { static void Main(string[] args) { // IObservable<T> と IObserver<T> を実装したクラスが提供されている var sbj = new Subject<string>(); // 通知先は関数を登録するだけでいい // 戻り値のオブジェクトは登録を解除するときに使う var d = sbj.Subscribe(s => Console.WriteLine("Subject: {0}", s)); // IObserver<T> を実装したクラスを登録することもできる sbj.Subscribe(new FooObserver()); // 通知を出す sbj.OnNext("Foo"); // 登録を解除 d.Dispose(); // 再び通知を出す // 「OnNext2:〜」は出力されないはず sbj.OnNext("Bar"); Console.ReadLine(); } } }
Suject