I have a list of Foo's
.
Foo
has a CreateDate
of type DateTime?
I want to get the oldest Foo
. I tryed with the intuitive way, but I get a possible System.InvalidOperationException
.
DateTime oldestFoo =
(from f in allFoos where f.CreateDate.HasValue select f.CreateDate.Value).Min();
Is there something I missed or is it just not possible this way?
I can do it without LinQ this way, but I want to learn the other approach too.
DateTime oldestFoo = DateTime.MaxValue;
foreach (var foo in allFoos)
{
if (foo.CreateDate.HasValue && oldestFoo > foo.CreateDate)
{
oldestFoo = (DateTime)foo.CreateDate;
}
}
Just in case you're still stuck, you might want to consider using DefaultIfEmpty
- see if this helps:
DateTime oldestFoo = allFoos.Where(f => f.CreateDate.HasValue)
.Select(f => f.CreateDate.Value)
.DefaultIfEmpty(DateTime.MaxValue)
.Min();
I don't think you want to use GetValueOrDefault
within your query, as otherwise you'll still have a problem if the first query returns no results at all.
You can use the GetValueOrDefault
method, which doesn't cause an exception, and as there are no null values at that point, the result is the same:
DateTime oldestFoo = (
from f in allFoos
where f.CreateDate.HasValue
select f.CreateDate.GetValueOrDefault()
).Min();
DateTime oldestFoo =
(from f in allFoos select f.CreateDate).Min() ?? DateTime.MaxValue;
Or, slightly more succinctly:
DateTime oldestFoo =
allFoos.Select(f => f.CreateDate).Min() ?? DateTime.MaxValue;
My suggestion is NOT to project DateTime?
to DateTime
before calling Min
.
Here's a Nullable<int>
sample that does not project to int
to illustrate how the Min
and Max
extensions behave with empty and different lists of nullable int's.
var foo = Enumerable.Empty<int?>();
Console.WriteLine(foo.Min());
foo = new int? [] { null, -20, 10 };
Console.WriteLine(foo.Min());
Console.WriteLine(foo.Max());
The output of the above is:
null
-20
10
Instead of filtering the DateTime?
instances in the list of Foos to only those that have values, allow the Min
extension to work with the DateTime?
values instead of projecting to DateTime
. When you have an empty list (as in the example above) you'll get a null
value from Min
instead of the InvalidOperationException
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.