C# 当使用Min或Max时,如何处理LINQ中的空值?
我有以下Linq查询:C# 当使用Min或Max时,如何处理LINQ中的空值?,c#,.net,linq,null,C#,.net,Linq,Null,我有以下Linq查询: result.Partials.Where(o => o.IsPositive).Min(o => o.Result) 当result.Partials.Where(o=>o.IsPositive)不包含元素时,会出现异常。除了将操作一分为二并检查null之外,还有什么优雅的方法来处理这个问题吗?我有一个像这样的操作类 编辑:该问题与LINQ到对象相关 这是我得到的例外(翻译为:序列为空): 如果序列为空,则不能使用Min(或Max)。如果不应该发生这种情况
result.Partials.Where(o => o.IsPositive).Min(o => o.Result)
当result.Partials.Where(o=>o.IsPositive)
不包含元素时,会出现异常。除了将操作一分为二并检查null之外,还有什么优雅的方法来处理这个问题吗?我有一个像这样的操作类
编辑:该问题与LINQ到对象相关
这是我得到的例外(翻译为:序列为空):
如果序列为空,则不能使用
Min
(或Max
)。如果不应该发生这种情况,那么如何定义结果
则是另一个问题。否则,应检查序列是否为空并进行适当处理,例如:
var query = result.Partials.Where(o => o.IsPositve);
min = query.Any() ? query.Min(o => o.Result) : 0; // insert a different "default" value of your choice...
您可以使用
DefaultIfEmpty
方法确保集合中至少有一项:
result.Partials.Where(o => o.IsPositive).Select(o => o.Result).DefaultIfEmpty().Min();
AMin
-无调解(例外!)
这是您的情况:如果没有匹配的元素,则Min
调用将引发异常(invalidooperationexception
)
-使用DefaultIfEmpty()
——仍然很麻烦
当列表中没有元素时,DefaultIfEmpty
将在0元素上创建枚举。您如何知道0是Min
,或者如果0表示没有元素的列表
-可为空的值;更好的解决方案
这里的Min
要么为空(因为它等于default(decimal?
),要么是找到的实际Min
因此,该结果的消费者将知道:
null
时,列表中没有元素Min
就是返回的值但是,如果这不重要,则可以调用
min.GetValueOrDefault(0)
。在LINQ中表达它的另一种方法是使用:
由于LINQ缺少像
MinOrDefault()
和MaxOrDefault()
这样的方法,您可以自己创建它们:
public static class LinqExtensions
{
public static TProp MinOrDefault<TItem, TProp>(this IEnumerable<TItem> This, Func<TItem, TProp> selector)
{
if (This.Count() > 0)
{
return This.Min(selector);
}
else
{
return default(TProp);
}
}
}
注意1:您不需要检查此
参数是否为空:调用的Count()
已经检查过了,并且它会引发与您将引发的相同的异常
注意2:此解决方案仅适用于调用
Count()
方法成本较低的情况。所有.NET集合都很好,因为它们都非常高效;对于特定的定制/非标准系列,这可能是一个问题。您会遇到什么例外?根据我的经验,如果Partials
为空,则应该得到0。堆栈跟踪调用了Min()
而不是Sum()
。结果是什么?对不起。我的错,操作是Min和Max而不是Sum。再次抱歉。编辑问题。您确定该行是引发异常的内容吗?异常是由Min()
方法引发的,而不是Where()
或Sum()
…如果默认值为null怎么办?@RitchMelton:我相信Min将返回null。我很确定使用null元素调用o.Result
会导致引发异常。@Ritch:是的,当然。我读的是decimal?
,而不是一般情况下的文档。将更新答案。太笨拙了。我使用与Adrian Iftode建议的方法相同的方法-将所选字段强制转换为nullable我想添加以下内容:如果您的属性为nullable,并且源集合可以包含null
值,则获得null
结果可能意味着两件事:要么集合没有元素,或者给定属性的所有值均为null
。
var min = result.Partials.Where(o => o.IsPositive)
.Select(o => o.Result)
.DefaultIfEmpty()
.Min();
var min = result.Partials.Where(o => o.IsPositive)
.Min(o => (decimal?)o.Result);
var min = result.Partials
.Where(o => o.IsPositive)
.Select(o => o.Result)
.Aggregate(0, Math.Min); // Or any other value which should be returned for empty list
public static class LinqExtensions
{
public static TProp MinOrDefault<TItem, TProp>(this IEnumerable<TItem> This, Func<TItem, TProp> selector)
{
if (This.Count() > 0)
{
return This.Min(selector);
}
else
{
return default(TProp);
}
}
}
public class Model
{
public int Result { get; set; }
}
// ...
public void SomeMethod()
{
Console.WriteLine("Hello World");
var filledList = new List<Model>
{
new Model { Result = 10 },
new Model { Result = 9 },
};
var emptyList = new List<Model>();
var minFromFilledList = filledList.MinOrDefault(o => o.Result)); // 9
var minFromEmptyList = emptyList.MinOrDefault(o => o.Result)); // 0
}