Search code examples
c#.netlinqnull

How to handle nulls in LINQ when using Min or Max?


I have the following Linq query:

result.Partials.Where(o => o.IsPositive).Min(o => o.Result)

I get an exception when result.Partials.Where(o => o.IsPositive) does not contains elements. Is there an elegant way to handle this other than splitting the operation in two and checking for null? I have a class full of operations like this one.

EDIT: The question is related with LINQ to Objects.

This is the Exception I'm getting (translated it says: The sequence is empty):

enter image description here


Solution

  • A short summary of the calculation of a Min

    - No mediation (Exception!)

       var min = result.Partials.Where(o => o.IsPositive).Min(o => o.Result);
    

    This is your case: if there are no matching elements, then the Min call will raise an exception (InvalidOperationException).

    - With DefaultIfEmpty() -- still troublesome

     var min = result.Partials.Where(o => o.IsPositive)
                              .Select(o => o.Result)
                              .DefaultIfEmpty()
                              .Min();
    

    DefaultIfEmpty will create an enumeration over the 0 element, when there are no elements in the list. How do you know that 0 is the Min or if 0 stands for a list with no elements?

    - Nullable values; A better solution

       var min = result.Partials.Where(o => o.IsPositive)
                                .Min(o => (decimal?)o.Result);
    

    Here Min is either null (because that's equal to default(decimal?)) or the actual Min found.

    So a consumer of this result will know that:

    1. When result is null then the list had no elements
    2. When the result is a decimal value then the list had some elements and the Min of those elements is that returned value.

    However, when this doesn't matter, then min.GetValueOrDefault(0) can be called.