Skip to content

FromEvent

1. 概要

FromEvent は、.NET のデリゲートベースのイベントを Observable シーケンスに変換するファクトリメソッドです。

Action ベースのイベントだけでなく、変換関数を渡すことで任意のカスタムデリゲート型のイベントにも対応できます。

通常は、対象のイベントが EventHandler / EventHandler<TEventArgs> パターンなら FromEventHandler を使います。FromEvent は、Action / Action<T> ベースのイベントや、独自デリゲート型のイベントを扱う場合に使います。

2. シグネチャ

Action ベース

csharp
public static Observable<Unit> FromEvent(Action<Action> addHandler, Action<Action> removeHandler, CancellationToken cancellationToken = default)

Action 型のイベントを Observable<Unit> に変換します。イベントが発火するたびに Unit を発行します。

csharp
Observable.FromEvent(
    h => source.OnAction += h,
    h => source.OnAction -= h)

Action<T> ベース

csharp
public static Observable<T> FromEvent<T>(Action<Action<T>> addHandler, Action<Action<T>> removeHandler, CancellationToken cancellationToken = default)

Action<T> 型のイベントを Observable<T> に変換します。イベントの引数がそのまま発行されます。

csharp
Observable.FromEvent<string>(
    h => source.OnMessage += h,
    h => source.OnMessage -= h)

カスタムデリゲート(Unit)

csharp
public static Observable<Unit> FromEvent<TDelegate>(Func<Action, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, CancellationToken cancellationToken = default)

独自のデリゲート型を持つイベントを Observable<Unit> に変換します。conversion 関数で Action をイベントのデリゲート型に変換します。

csharp
Observable.FromEvent<MyDelegate>(
    action => new MyDelegate(() => action()),
    h => source.OnCustom += h,
    h => source.OnCustom -= h)

カスタムデリゲート(T)

csharp
public static Observable<T> FromEvent<TDelegate, T>(Func<Action<T>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, CancellationToken cancellationToken = default)

独自のデリゲート型を持つイベントを Observable<T> に変換します。conversion 関数で Action<T> をイベントのデリゲート型に変換し、イベント引数を発行します。

csharp
Observable.FromEvent<MyDelegate, int>(
    action => new MyDelegate(value => action(value)),
    h => source.OnValueChanged += h,
    h => source.OnValueChanged -= h)

オーバーロードの使い分け

オーバーロード使う場面
FromEvent(Action<Action>, ...)Action 型のイベント(引数なし)
FromEvent<T>(Action<Action<T>>, ...)Action<T> 型のイベント(引数あり)
FromEvent<TDelegate>(Func<Action, TDelegate>, ...)カスタムデリゲートのイベント(引数なし)
FromEvent<TDelegate, T>(Func<Action<T>, TDelegate>, ...)カスタムデリゲートのイベント(引数あり)

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

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

イベントが発火するたびに対応する値(Unit または T)が発行されます。CancellationToken がキャンセルされるとイベントハンドラが解除され、シーケンスが完了します。

4. サンプルコード

csharp
using R3;

// === Action ベースのイベント ===
var cts = new CancellationTokenSource();

// ボタンのクリックイベントなど
Observable.FromEvent(
        h => button.OnClick += h,
        h => button.OnClick -= h,
        cts.Token)
    .Subscribe(_ => Console.WriteLine("クリックされました"));

// === Action<T> ベースのイベント ===
// メッセージ受信イベント
Observable.FromEvent<string>(
        h => messenger.OnMessageReceived += h,
        h => messenger.OnMessageReceived -= h)
    .Subscribe(msg => Console.WriteLine($"受信: {msg}"));
// 出力例: 受信: Hello

// === カスタムデリゲートのイベント ===
// delegate void ValueChangedHandler(int oldValue, int newValue);
// 引数を 1 つにまとめて変換する
Observable.FromEvent<ValueChangedHandler, (int Old, int New)>(
        action => new ValueChangedHandler((o, n) => action((o, n))),
        h => source.ValueChanged += h,
        h => source.ValueChanged -= h)
    .Subscribe(x => Console.WriteLine($"変更: {x.Old} → {x.New}"));
// 出力例: 変更: 0 → 42

5. 補足

FromEventHandler との違い

FromEventHandlerEventHandler / EventHandler<TEventArgs> パターン専用の簡便メソッドです。標準的な .NET イベントパターン(sender + EventArgs)を使っている場合は FromEventHandler のほうが簡潔に記述できます。FromEvent はそれ以外のすべてのデリゲート型に対応する汎用メソッドです。