Net Q & A: how to avoid the exception thrown by max() on emptyenumerable?

Consultation area

Naor:

I have the following query:


int maxShoeSize = Workers.Where(=> x.CompanyId == 8)
                          .Max(=> x.ShoeSize);

If workers. Where (x = & gt; x. Companyid = = 8) if no workers are found, the above code will throw an exception.

Now the idea is: query can return 0 if it can't be found, but don't throw an exception. How can I modify the query above?

Answer area

Ron K.:

You can use the extension method of IEnumerable defaultifempty() to avoid this embarrassment. Refer to the following code.

     class Program     {         static void Main(string[] args)         {             List<Worker> Workers = new List<Worker>()             {                 new Worker(){ CompanyId=1, CompanyName="tweet", ShoeSize=10 },                 new Worker(){ CompanyId=2, CompanyName="google", ShoeSize=20 },             };             int maxShoeSize = Workers.Where(=> x.CompanyId == 8)                           .Select(=> x.ShoeSize)                           .DefaultIfEmpty(0)                           .Max();             Debug.WriteLine($"maxShoeSize={maxShoeSize}");         }     }     class Worker     {         public int CompanyId { get; set; }         public string CompanyName { get; set; }         public int ShoeSize { get; set; }     } 

Output results:

 maxShoeSize=0 

Of course, the above 0 is not necessary. You can change it to any other number.

CptRobby

Although the plan provided by the man upstairs can work normally, it doesn't look very eye-catching. It can be transformed into the following one.

     int maxShoeSize = Workers.Where(=> x.CompanyId == 8)                              .Select(=> (int?)x.ShoeSize)                               .Max() ?? 0; 

Does the code look a little lengthy?The best way is to customize a extension method , as shown in the following code:

 public static int MaxOrDefault<T>(this IQueryable<T> source, Expression<Func<T, int?>> selector, int nullValue = 0) {     return source.Max(selector) ?? nullValue; } 

For simplicity, this extension only deals with the int type. You can change it to any type, such as: (long, double,...), and then you can continue to reform the caller.

 int maxShoeSize = Workers.Where(=> x.CompanyId == 8).MaxOrDefault(=> x.ShoeSize); 

I hope my answer can help more people.

Comment area

Xiaobian never dares to do Max on the empty collection , after all, it's not once or twice, so every time we judge whether there is a value in the collection in advance, and then execute Max , we didn't expect that there are magic extension methods defaultifempty and empty type that can help us to do it, and we all forget about sensory science????????????.

Read More: