Skip to content

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 のマーブルダイアグラム

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();