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)predicate が true を返す要素がちょうど 1 つだけの場合は、その要素を返します。条件を満たす要素がない場合は defaultValue を返し、2 個以上ある場合は例外をスローします。
オーバーロードの使い分け
| オーバーロード | 用途 |
|---|---|
SingleOrDefaultAsync(source) | 空のシーケンスで default(T) を返したい場合 |
SingleOrDefaultAsync(source, defaultValue) | 空のシーケンスで特定のデフォルト値を返したい場合 |
| 条件あり | 条件を満たす要素が 1 つだけなら取得し、見つからない場合にデフォルト値を返したい場合 |
3. マーブルダイアグラム
シーケンスが唯一の要素で完了した場合にその値を、空の場合にデフォルト値を出力します。要素が 2 個以上の場合はエラーとなります。
4. サンプルコード
csharp
// 要素が 1 つだけのシーケンス → その要素を返す
var source = Observable.Return(42);
int? value = await source.SingleOrDefaultAsync();
Console.WriteLine(value); // 42csharp
// 条件を満たす要素が 1 つだけ → その要素を返す
var source = new[] { 10, 15, 20, 25 }.ToObservable();
int value = await source.SingleOrDefaultAsync(x => x == 20);
Console.WriteLine(value); // 20csharp
// 空のシーケンス → デフォルト値を返す
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); // -1csharp
// 条件を満たす要素がない場合に指定したデフォルト値を返す
var source = new[] { 10, 15, 20 }.ToObservable();
int value = await source.SingleOrDefaultAsync(x => x > 100, -1);
Console.WriteLine(value); // -1csharp
// 複数要素のシーケンス → 例外
try
{
var multiple = new[] { 1, 2, 3 }.ToObservable();
int? value = await multiple.SingleOrDefaultAsync();
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.Message); // シーケンスに複数の要素が含まれています
}