Materialize / Dematerialize
1. 概要
Materialize は、上流の OnNext・OnErrorResume・OnCompleted 通知をすべて Notification<T> オブジェクトに包み、通常の値として下流へ流すオペレーターです。
Dematerialize はその逆で、Observable<Notification<T>> を元の通知に戻します。
この 2 つは逆操作のペアです。通知の種類に応じた分岐処理やログ出力、通知レベルでの変換・フィルタリングを行いたい場合に活用します。
2. シグネチャ
通知を Notification<T> に包む(Materialize)
csharp
public static Observable<Notification<T>> Materialize<T>(this Observable<T> source)上流の OnNext(value) は Notification<T>(value) に、OnErrorResume(error) は Notification<T>(error) に、OnCompleted(result) は Notification<T>(result) に変換されます。OnCompleted は Notification<T> を発行した直後に完了通知として下流へ伝搬されます。
csharp
source.Materialize()Notification<T> を元の通知に戻す(Dematerialize)
csharp
public static Observable<T> Dematerialize<T>(this Observable<Notification<T>> source)Notification<T> の Kind に応じて、元の OnNext・OnErrorResume・OnCompleted 通知に復元します。
csharp
source.Dematerialize()3. マーブルダイアグラム
上流から 1、2 が流れて完了した場合、Materialize を通すと OnNext(1)、OnNext(2)、OnCompleted がそれぞれ Notification<int> として下流へ流れます。
4. サンプルコード
csharp
using R3;
var source = Observable.Create<int>(observer =>
{
observer.OnNext(1);
observer.OnNext(2);
observer.OnNext(3);
observer.OnCompleted();
return Disposable.Empty;
});
// Materialize: すべての通知を値として観察する
source.Materialize()
.Subscribe(n => Console.WriteLine($"Kind={n.Kind}, Value={n.Value}"));
// 出力:
// Kind=OnNext, Value=1
// Kind=OnNext, Value=2
// Kind=OnNext, Value=3
// Kind=OnCompleted, Value=...Materialize → 変換 → Dematerialize のパターン:
csharp
using R3;
var source = Observable.Range(1, 3);
// 通知レベルで操作してから元に戻す
source
.Materialize()
.Do(n => Console.WriteLine($"通知: {n.Kind}"))
.Dematerialize()
.Subscribe(x => Console.WriteLine($"値: {x}"));
// 出力:
// 通知: OnNext
// 値: 1
// 通知: OnNext
// 値: 2
// 通知: OnNext
// 値: 3
// 通知: OnCompleted