web-dev-qa-db-ja.com

シーケンスが空の場合にLINQのMax関数がデフォルト値を返すようにするにはどうすればよいですか?

私はこのコードを持っています:

List<int> myList = new List<int>();
var max = myList.Max();
Console.Write(max);

リストに要素がない場合は、int(0)のデフォルト値を使用する必要があります。しかし、代わりにInvalidOperationExceptionがスローされ、「シーケンスに要素が含まれていません」と示されています。

もちろん、Anyまたはクエリ構文( here のように)を使用することもできます。しかし、私は流暢な構文を使用してそれをやりたいです。

どうすればこれを修正できますか?

34
Royi Namir

これを試して:

var myList = new List<int>();
var max = myList.DefaultIfEmpty().Max();
Console.Write(max);

LINQのDefaultIfEmpty-メソッドは、シーケンスが空かどうかをチェックします。その場合、シングルトンシーケンスが返されます。1つの要素のみを含むシーケンスです。この1つの要素には、シーケンスのタイプのデフォルト値があります。シーケンスに要素が含まれている場合、DefaultIfEmpty-メソッドは単にシーケンス自体を返します。

詳細については、MSDNを参照してください

78
Spontifixus

拡張機能はどうですか?

public static int MaxOrDefault<T>(this IEnumerable<T> enumeration, Func<T, int> selector)
{
    return enumeration.Any() ? enumeration.Max(selector) : default(int);
}
5
Alvaro Rivoir

Enumerable.Aggregateを使用する場合、空のリストの場合に特別な処理を行う必要はありません。これを試して:

List<int> myList = new List<int>();
var max = myList.Aggregate(default(int), (seed, i) => (i > seed ? i : seed));
Console.Write(max);
3
Bill Stanton

少し接線にありますが、おそらくまだ有用です。別の解決策は、値をnull許容型にキャストすることです。

var myInt = new Int[0].Max(i=>(int?)i);//myInt == null
2
Myles McDonnell