如果序列为空,如何使LINQ的Max-function返回默认值?

时间:2012-11-08 08:08:16

标签: c# linq .net-4.0

我有这段代码:

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

我希望确保如果列表中没有元素,则应使用int(0)的默认值。但是反而引发了InvalidOperationException,声明“序列不包含任何元素”。

当然,我可以使用Any或查询语法(如here中所述)。但我想用流利的语法来做到这一点。

我该如何解决这个问题?

5 个答案:

答案 0 :(得分:66)

试试这个:

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

LINQ的DefaultIfEmpty - 方法检查序列是否为空。如果是这种情况,它将返回一个单例序列:一个只包含一个元素的序列。这一个元素具有序列类型的默认值。如果序列确实包含元素,DefaultIfEmpty - 方法将只返回序列本身。

有关详细信息,请参阅MSDN

答案 1 :(得分:3)

如果使用Enumerable.Aggregate,则对于空列表的情况将不需要任何特殊处理。试试这个:

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

答案 2 :(得分:2)

略微处于切线但可能仍然有用..另一种解决方案是将值转换为可空类型;

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

答案 3 :(得分:2)

扩展名呢?

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

答案 4 :(得分:0)

作为扩展方法,@ AlvaroRivoir的解决方案可以通过添加其他类型参数的进一步泛化来扩展:

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