Skip to content

SingleOrDefaultAsync

1. 概要

SingleOrDefaultAsync は、Observable シーケンスの唯一の要素、または条件を満たす唯一の要素を取り出し、その結果を Task として返すオペレーターです。対象となる要素がない場合はデフォルト値を返します。対象要素が 2 個以上ある場合は InvalidOperationException をスローします。

2. シグネチャ

型のデフォルト値を使用

csharp
public static Task<T?> SingleOrDefaultAsync<T>(
    this Observable<T> source,
    CancellationToken cancellationToken = default)

シーケンスが空の場合、default(T) を返します。参照型の場合は null、値型の場合はその型のデフォルト値になります。

カスタムデフォルト値を指定

csharp
public static Task<T> SingleOrDefaultAsync<T>(
    this Observable<T> source,
    T defaultValue,
    CancellationToken cancellationToken = default)

シーケンスが空の場合に返すデフォルト値を明示的に指定します。

条件を満たす唯一の要素を取得

csharp
public static Task<T> SingleOrDefaultAsync<T>(
    this Observable<T> source,
    Func<T, Boolean> predicate,
    T defaultValue = default,
    CancellationToken cancellationToken = default)

predicatetrue を返す要素がちょうど 1 つだけの場合は、その要素を返します。条件を満たす要素がない場合は defaultValue を返し、2 個以上ある場合は例外をスローします。

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

オーバーロード用途
SingleOrDefaultAsync(source)空のシーケンスで default(T) を返したい場合
SingleOrDefaultAsync(source, defaultValue)空のシーケンスで特定のデフォルト値を返したい場合
条件あり条件を満たす要素が 1 つだけなら取得し、見つからない場合にデフォルト値を返したい場合

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

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

シーケンスが唯一の要素で完了した場合にその値を、空の場合にデフォルト値を出力します。要素が 2 個以上の場合はエラーとなります。

4. サンプルコード

csharp
// 要素が 1 つだけのシーケンス → その要素を返す
var source = Observable.Return(42);

int? value = await source.SingleOrDefaultAsync();
Console.WriteLine(value); // 42
csharp
// 条件を満たす要素が 1 つだけ → その要素を返す
var source = new[] { 10, 15, 20, 25 }.ToObservable();

int value = await source.SingleOrDefaultAsync(x => x == 20);
Console.WriteLine(value); // 20
csharp
// 空のシーケンス → デフォルト値を返す
var empty = Observable.Empty<int>();

int? value = await empty.SingleOrDefaultAsync();
Console.WriteLine(value); // 0(int のデフォルト値)
csharp
// カスタムデフォルト値を指定
var empty = Observable.Empty<int>();

int value = await empty.SingleOrDefaultAsync(-1);
Console.WriteLine(value); // -1
csharp
// 条件を満たす要素がない場合に指定したデフォルト値を返す
var source = new[] { 10, 15, 20 }.ToObservable();

int value = await source.SingleOrDefaultAsync(x => x > 100, -1);
Console.WriteLine(value); // -1
csharp
// 複数要素のシーケンス → 例外
try
{
    var multiple = new[] { 1, 2, 3 }.ToObservable();
    int? value = await multiple.SingleOrDefaultAsync();
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex.Message); // シーケンスに複数の要素が含まれています
}