[英]How to handle nulls in LINQ when using Min or Max?
我有以下 Linq 查詢:
result.Partials.Where(o => o.IsPositive).Min(o => o.Result)
當result.Partials.Where(o => o.IsPositive)
不包含元素時,我得到一個異常。 除了將操作一分為二並檢查是否為空之外,是否有一種優雅的方法來處理這個問題? 我有一堂課充滿了這樣的操作。
編輯:問題與 LINQ to Objects 有關。
這是我得到的異常(翻譯它說:序列為空):
Min
計算的簡短摘要 var min = result.Partials.Where(o => o.IsPositive).Min(o => o.Result);
這是您的情況:如果沒有匹配的元素,則Min
調用將引發異常( InvalidOperationException
)。
DefaultIfEmpty()
-- 仍然很麻煩 var min = result.Partials.Where(o => o.IsPositive)
.Select(o => o.Result)
.DefaultIfEmpty()
.Min();
當列表中沒有元素時, DefaultIfEmpty
將在 0 元素上創建一個枚舉。 你怎么知道 0 是Min
還是 0 代表沒有元素的列表?
var min = result.Partials.Where(o => o.IsPositive)
.Min(o => (decimal?)o.Result);
這里Min
要么是 null (因為它等於default(decimal?)
)要么是實際找到的Min
。
所以這個結果的消費者會知道:
null
,列表沒有元素Min
是返回值。 但是,當這無關緊要時,可以調用min.GetValueOrDefault(0)
。
您可以使用DefaultIfEmpty
方法來確保集合至少有 1 個項目:
result.Partials.Where(o => o.IsPositive).Select(o => o.Result).DefaultIfEmpty().Min();
如果序列為空,則不能使用Min
(或Max
)。 如果這不應該發生,那么您對如何定義result
會有不同的問題。 否則,您應該檢查序列是否為空並進行適當處理,例如:
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...
在 LINQ 中表達它的另一種方法是使用Aggregate :
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
由於 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);
}
}
}
因此,如果集合有值,則計算Min()
,否則獲得屬性類型的默認值。
使用示例:
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
}
注意 1 :您不需要檢查This
參數是否為空:調用的Count()
已經檢查過,並且它會拋出與您將拋出的相同的異常。
注意 2 :此解決方案僅適用於Count()
方法調用成本低的情況。 所有 .NET 集合都很好,因為它們都非常高效; 對於特定的定制/非標准集合,這可能是一個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.