Do
1. 概要
Do は、Observable シーケンスの各ライフサイクルイベント(要素の発行、エラー、完了、購読、破棄)に副作用を挿入するオペレーターです。シーケンスの内容自体は一切変更せず、デバッグやログ出力などの目的で利用されます。
2. シグネチャ
アクションデリゲート指定オーバーロード
csharp
public static Observable<T> Do<T>(
this Observable<T> source,
Action<T>? onNext = null,
Action<Exception>? onErrorResume = null,
Action<Result>? onCompleted = null,
Action? onDispose = null,
Action? onSubscribe = null)各ライフサイクルイベントに対応するアクションデリゲートを個別に指定します。不要なイベントは省略(null)できます。
ステート付きオーバーロード
csharp
public static Observable<T> Do<T, TState>(
this Observable<T> source,
TState state,
Action<T, TState>? onNext = null,
Action<Exception, TState>? onErrorResume = null,
Action<Result, TState>? onCompleted = null,
Action<TState>? onDispose = null,
Action<TState>? onSubscribe = null)外部状態 TState をデリゲートに渡すことで、クロージャによるメモリアロケーションを回避できます。パフォーマンスが重要な場面で推奨されます。
overload の使い分け
| オーバーロード | 用途 |
|---|---|
| アクションデリゲート指定 | 簡易なデバッグやログ出力。手軽に副作用を挿入したい場合。 |
| ステート付き | パフォーマンスが重要な場面。クロージャのアロケーションを避けたい場合。 |
3. マーブルダイアグラム
Do はソースシーケンスの各要素をそのまま下流に流しながら、指定された副作用アクションを実行します。シーケンスの出力は入力と完全に同一です。
4. サンプルコード
csharp
// 基本的なログ出力
var source = new Subject<int>();
source.Do(
onNext: x => Console.WriteLine($"[LOG] OnNext: {x}"),
onErrorResume: ex => Console.WriteLine($"[LOG] OnErrorResume: {ex.Message}"),
onCompleted: result => Console.WriteLine($"[LOG] OnCompleted: {result}"),
onSubscribe: () => Console.WriteLine("[LOG] Subscribed"),
onDispose: () => Console.WriteLine("[LOG] Disposed"))
.Subscribe();
source.OnNext(1); // [LOG] OnNext: 1
source.OnNext(2); // [LOG] OnNext: 2
source.OnCompleted(); // [LOG] OnCompleted: ...csharp
// ステート付きオーバーロードでアロケーション回避
var logger = new MyLogger();
source.Do(
state: logger,
onNext: static (x, log) => log.Write($"Value: {x}"))
.Subscribe();