Skip to content

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) に変換されます。OnCompletedNotification<T> を発行した直後に完了通知として下流へ伝搬されます。

csharp
source.Materialize()

Notification<T> を元の通知に戻す(Dematerialize)

csharp
public static Observable<T> Dematerialize<T>(this Observable<Notification<T>> source)

Notification<T>Kind に応じて、元の OnNextOnErrorResumeOnCompleted 通知に復元します。

csharp
source.Dematerialize()

3. マーブルダイアグラム

Materialize のマーブルダイアグラム

上流から 12 が流れて完了した場合、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