When you start playing with LINQ queries over sequences of elements (e.g. getting min / max value for enumerable source) sooner or later you will come across this one -- the InvalidOperationException (“Sequence contains no elements”).

The problem occurs as by default queries like IEnumerable<T>.Min(…) and IEnumerable<T>.Max(…) do not play nicely if you try to execute them on an empty sequence and just throw the exception described above. Unfortunately these methods do not have a corresponding counterpart like Single(…) / SingleOrDefault(…) that is smart enough to query the sequence if it is not empty or alternatively use the default value without raising an exception.

Basically you got two options now:

  • Either perform the check on the enumerable sequence every time you are querying it
  • OR integrate the logic in an extension method.

The second approach is much preferable so let’s add the missing link below:

namespace ExtensionMethods
{
   
using System;
   
using System.Collections.Generic;
   
using System.Linq;

   
public static class IEnumerableExtensions
   
{
       
/// <summary>
        /// Invokes a transform function on each element of a sequence and returns the minimum Double value 
        /// if the sequence is not empty; otherwise returns the specified default value. 
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of source.</typeparam>
        /// <param name="source">A sequence of values to determine the minimum value of.</param>
        /// <param name="selector">A transform function to apply to each element.</param>
        /// <param name="defaultValue">The default value.</param>
        /// <returns>The minimum value in the sequence or default value if sequence is empty.</returns>
        public static double MinOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector, double defaultValue)
       
{
           
if (source.Any<TSource>())
               
return source.Min<TSource>(selector); 

           
return defaultValue;
       
}

       
/// <summary>
        /// Invokes a transform function on each element of a sequence and returns the maximum Double value 
        /// if the sequence is not empty; otherwise returns the specified default value. 
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of source.</typeparam>
        /// <param name="source">A sequence of values to determine the maximum value of.</param>
        /// <param name="selector">A transform function to apply to each element.</param>
        /// <param name="defaultValue">The default value.</param>
        /// <returns>The maximum value in the sequence or default value if sequence is empty.</returns>
        public static double MaxOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector, double defaultValue)
       
{
           
if (source.Any<TSource>())
               
return source.Max<TSource>(selector); 

           
return defaultValue;
       
}
   
}
}
 
Now you only need to add the using ExtensionMethods; directive in your project and you are all set:
extensionmethods
 
 
Hope this helps.

Related Posts

Comments

Comments are disabled in preview mode.