33

Possible Duplicate:
LINQ: Max or Default?

I have some LINQ to filter DateTime vars.

List<DateTime> lst1 = new List<DateTime>();

 //.... add DataTime here

var d = lst1.Where(q => q <= DateTime.Now).Max();

And if I have no matched item the exceptions occurs.

I need to get empty d or at least null and I don't need exception here at all.

How do I can fix it?

Thank you!

abatishchev
  • 98,240
  • 88
  • 296
  • 433
NoWar
  • 36,338
  • 80
  • 323
  • 498
  • 1
    check before var d=... like if (lst1.Where(q => q <= DateTime.Now) == null)) return null; – MiBu Aug 09 '12 at 13:10
  • 1
    var d = lst1.Any()? lst1.Where(q => q <= DateTime.Now).Max():new DateTime(1900,1,1); – huMpty duMpty Aug 09 '12 at 13:12
  • http://stackoverflow.com/questions/341264/linq-max-or-default – pymendoza Aug 09 '12 at 13:12
  • http://geekswithblogs.net/SoftwareDoneRight/archive/2011/02/15/fixing-linq-error-sequence-contains-no-elements.aspx shows a solution like this: var d = lst1.Where(q=> a <= DateTime.Now).DefaultIfEmpty().Max(d => d == null? DateTime.Min : d) – Greg Gum Jun 20 '13 at 19:04

3 Answers3

82

Try

var d = lst1.Where(q => q <= DateTime.Now).DefaultIfEmpty().Max();

Your result will now contain DateTime.MinValue if there are no matches

podiluska
  • 50,950
  • 7
  • 98
  • 104
  • podiluska, you may want to explain to the OP why your solution now shows a Date Value for lst1 your solution is perfect but I am not sure if he will understand why. – MethodMan Aug 09 '12 at 13:17
  • 3
    Note that if you want the max value of a property off of lst1, you will need to account for null. eg: `var maxHeight = lst1.Where(q => q <= DateTime.Now).DefaultIfEmpty().Max(q => q?.height ?? 0);` – Nate Radebaugh Jan 09 '18 at 13:04
  • In the off chance anybody is doing this for a UWP app, you'll get a very strange error regarding "multiple inheritance" if you attempt to build the app in release mode with .NET Native toolchain enabled. it is due to using "DefaultIfEmpty()", so instead of that I would recommend just writing a custom extension method that checks if what is returned from Where is null or empty and if so return what you want, otherwise proceed with the agg function you want to use (.Max, .Average) etc. – Mark Z. Feb 11 '20 at 10:20
5

Max() throws an ArgumentNullException if the source doesn't have any elements. You could write an extension method that checks for this and returns a null (or whatever you want) if there aren't any elements.

public static Nullable<DateTime> MaxOrNull(this IEnumerable<DateTime> source)
{
    if (source.Count() == 0)
        return null;
    else
        return source.Max();
}
lurkerguy
  • 64
  • 3
  • 5
    I would use `if (source.Any() == false)` instead of `if (source.Count() == 0)`. You don't need to count to check if the list is empty or not. – Maxime Dec 07 '15 at 20:49
  • This would be more efficient, as it will return true upon the first element found. return source.Any() ? source.Max() : null; – Jordan Nov 28 '16 at 18:45
1

I like:

var d = lst1.Where(q => q <= DateTime.Now).OrderByDescending(q => q.DateField).FirstOrDefault();

This will return a null if the list is empty.

Daniel
  • 10,864
  • 22
  • 84
  • 115
  • Let N is the length of lst1, then Max requires exactly N compare, the OrderBy requires N*log(N) in best case in best implementation, N*N/2 in worst. Or course it does not matter if N is small but N ~1000 it makes a big difference. – Peter Krassoi Jul 26 '17 at 09:01