過去記事インデックス
- Reactive Extensions再入門 その1
- Reactive Extensions再入門 その2「IObservableインターフェースとIObserverインターフェース」
- Reactive Extensions再入門 その3「IObservableのファクトリメソッド」
- Reactive Extensions再入門 その4「Timer系のファクトリメソッド」
- Reactive Extensions再入門 その5「HotとCold」
- Reactive Extensions再入門 その6「HotなIObservableを作成するファクトリ」
- Reactive Extensions再入門 その7「LINQスタイルの拡張メソッド」
- Reactive Extensions再入門 その8「SkipとTakeメソッド」
- Reactive Extensions再入門 その9「Skip + Take + Repeat = ドラッグ」
- Reactive Extensions再入門 その10「Doメソッド」
- Reactive Extensions再入門 その11「Catchメソッド」
- Reactive Extensions再入門 その12「Finallyメソッドとリソース解放」
- Reactive Extensions再入門 その13「最後の値を取得するLatestとMostRecentメソッド」
- Reactive Extensions再入門 その14「Nextメソッド」
- Reactive Extensions再入門 その15「To*****系メソッド」
- Reactive Extensions再入門 その16「最大、最少、平均を求めるメソッド」
- Reactive Extensions再入門 その17「集計するメソッド」
- Reactive Extensions再入門 その18「CountメソッドとLongCountメソッド」
- Reactive Extensions再入門 その19「AnyメソッドとAllメソッド」
- Reactive Extensions再入門 その20「GroupByメソッドでグルーピングしてみよう」
- Reactive Extensions再入門 その21「GroupByUntilメソッド」
- Reactive Extensions再入門 その22「単一の値を取得するメソッド」
- Reactive Extensions再入門 その23「重複を排除するメソッド」
- Reactive Extensions再入門 その24「単一の値を取得するメソッド その2」
- Reactive Extensions再入門 その25「値をまとめるBufferメソッド」
- Reactive Extensions再入門 その26「値をまとめるWindowメソッド」
- Reactive Extensions再入門 その27「時間でフィルタリング?Sampleメソッド」
- Reactive Extensions再入門 その28「落ち着いたら流すThrottleメソッド」
- Reactive Extensions再入門 その29「値を指定した時間だけ遅延させるDelayメソッド」
- Reactive Extensions再入門 その30「もう待ちきれない!を表現するTimeoutメソッド」
- Reactive Extensions再入門 その31「時間に関する情報を付与するTimestampとTimeIntervalメソッド」
- Reactive Extensions再入門 その32「型変換を行うCastとOfTypeメソッド」
- Reactive Extensions再入門 その33「シーケンスの最後を起点にSkipとTake」
- Reactive Extensions再入門 その34「ダメなら次の人!を実現するOnErrorResumeNextメソッド」
- Reactive Extensions再入門 その35「駄目ならやり直す!を実現するRetryメソッド」
- Reactive Extensions再入門 その36「ColdからHotへ!Publishメソッドと参照カウンタ?RefCountメソッド」
- Reactive Extensions再入門 その37「ColdからHotへ!その他のPublish系メソッド」
- Reactive Extensions再入門 その38「ColdからHotへ!その他のPublish系メソッド2」
- Reactive Extensions再入門 その39「Subject系クラス」
- Reactive Extensions再入門 その40「IObservableの合成はじめました」
- Reactive Extensions再入門 その41「どんどん合成するよ」
- Reactive Extensions再入門 その42「StartWithメソッドとJoinメソッド」
- Reactive Extensions再入門 その43「GroupJoinメソッド」
はじめに
合成系メソッドの紹介も今回で最後の予定です!今回は、個人的に理解にてこずったWhenメソッドと、その周辺メソッド達です。
Whenメソッド
ここではWhenメソッドについて説明します。Whenメソッドのシグネチャを以下に示します。
public static IObservable<TResult> When<TResult>(params Plan<TResult>[] plans); public static IObservable<TResult> When<TResult>(this IEnumerable<Plan<TResult>> plans);
Whenメソッドには2つのオーバーロードがあり、片方がPlan
Planクラスの作成
Whenメソッドの引数に渡すPlan
public static Pattern<TLeft, TRight> And<TLeft, TRight>( this IObservable<TLeft> left, IObservable<TRight> right);
この戻り値のPattern
public Pattern<T1, T2, T3> And<T3>(IObservable<T3> other);
このように、このPattern
Patternクラスには型引数の数の引数を受け取るデリゲートを受け取るThenメソッドが定義されています。Pattern
public Plan<TResult> Then<TResult>(Func<T1, T2, T3, TResult> selector);
このメソッドからPlan
Whenメソッドの使用例
では、上記のAndメソッドとThenメソッドを使ってPlan
var plan = Observable // plan1という文字列を10個発行するIObservable<string> .Return("plan1").Repeat(10) // 1秒間隔で0からのカウントアップにタイムスタンプをつけるIObservable<Timestamped<long>> .And(Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp()) // 100〜110の値を発行するIObservable<int> .And(Observable.Range(100, 10)) // 3つの値を文字列として纏める .Then((planName, timestamped, value) => string.Format("{0} {1} {2}", planName, timestamped, value)); // WhenでPlan<string>からIObservable<string>にして購読 Observable.When(plan).Subscribe( s => Console.WriteLine("OnNext: {0}", s), () => Console.WriteLine("OnCompleted")); Console.ReadLine();
コメントにある通りですが、無限に値を発行し続けるIObservable
OnNext: plan1 0@2012/02/22 23:47:09 +09:00 100 OnNext: plan1 1@2012/02/22 23:47:10 +09:00 101 OnNext: plan1 2@2012/02/22 23:47:11 +09:00 102 OnNext: plan1 3@2012/02/22 23:47:12 +09:00 103 OnNext: plan1 4@2012/02/22 23:47:13 +09:00 104 OnNext: plan1 5@2012/02/22 23:47:14 +09:00 105 OnNext: plan1 6@2012/02/22 23:47:15 +09:00 106 OnNext: plan1 7@2012/02/22 23:47:16 +09:00 107 OnNext: plan1 8@2012/02/22 23:47:17 +09:00 108 OnNext: plan1 9@2012/02/22 23:47:18 +09:00 109 OnCompleted
Andで連結したIObservable
次に、複数のPlan
var plan1 = Observable // plan1という文字列を10個発行するIObservable<string> .Return("plan1").Repeat(10) // 1秒間隔で0からのカウントアップにタイムスタンプをつけるIObservable<Timestamped<long>> .And(Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp()) // 100〜110の値を発行するIObservable<int> .And(Observable.Range(100, 10)) // 3つの値を文字列として纏める .Then((planName, timestamped, value) => string.Format("{0} {1} {2}", planName, timestamped, value)); var plan2 = Observable // plan2という文字列を20個発行するIObservable<string> .Return("plan2").Repeat(20) // 0.5s間隔で0から値を発行していくIObservable<long> .And(Observable.Interval(TimeSpan.FromSeconds(0.5))) // Thenで文字列に纏める .Then((s, l) => string.Format("{0} {1}", s, l)); Observable.When(plan1, plan2).Subscribe( s => Console.WriteLine("OnNext: {0}", s), () => Console.WriteLine("OnCompleted"));
plan1は、最初の例と同じように作成しています。plan2は、20個のplan2という文字列と、0.5秒間隔で0から値をカウントアップしていくIObservable
OnNext: plan2 0 OnNext: plan1 0@2012/02/22 23:53:21 +09:00 100 OnNext: plan2 1 OnNext: plan2 2 OnNext: plan2 3 OnNext: plan1 1@2012/02/22 23:53:22 +09:00 101 OnNext: plan2 4 OnNext: plan2 5 OnNext: plan1 2@2012/02/22 23:53:23 +09:00 102 OnNext: plan2 6 OnNext: plan2 7 OnNext: plan1 3@2012/02/22 23:53:24 +09:00 103 OnNext: plan2 8 OnNext: plan2 9 OnNext: plan1 4@2012/02/22 23:53:25 +09:00 104 OnNext: plan2 10 OnNext: plan2 11 OnNext: plan1 5@2012/02/22 23:53:26 +09:00 105 OnNext: plan2 12 OnNext: plan2 13 OnNext: plan1 6@2012/02/22 23:53:27 +09:00 106 OnNext: plan2 14 OnNext: plan2 15 OnNext: plan1 7@2012/02/22 23:53:28 +09:00 107 OnNext: plan2 16 OnNext: plan2 17 OnNext: plan1 8@2012/02/22 23:53:29 +09:00 108 OnNext: plan2 18 OnNext: plan1 9@2012/02/22 23:53:30 +09:00 109 OnNext: plan2 19 OnCompleted
plan1から発行された値と、plan2から発行された値が混在して表示されていることが確認できます。このことからWhenで繋いだPlan
まとめ
このようにAndメソッドは使ってZipメソッドのように複数のIObservable
恐らく合成系のメソッドの中で一番自由度が高く複雑な合成が出来るメソッドになります。