C# 如何使用LINQ从对象集合中获取最新日期?

C# 如何使用LINQ从对象集合中获取最新日期?,c#,linq,collections,C#,Linq,Collections,我有一个对象列表,每个对象都有一个ExpirationDate属性,该属性的类型为DateTime。我想检索列表中的最新日期。有没有一种优雅的方式可以通过LINQ做到这一点 比如: DateTime latestDate = myCollection.Where(r=>r.ExpirationDate.HasValue).MaxDate(r=>r.ExpirationDate.Value); 你就快到了。使用最大值: DateTime? biggest = myCollectio

我有一个对象列表,每个对象都有一个ExpirationDate属性,该属性的类型为DateTime。我想检索列表中的最新日期。有没有一种优雅的方式可以通过LINQ做到这一点

比如:

DateTime latestDate =  myCollection.Where(r=>r.ExpirationDate.HasValue).MaxDate(r=>r.ExpirationDate.Value);

你就快到了。使用最大值:

DateTime? biggest = myCollection.Max(r=>r.ExpirationDate);
如果所有过期日期均为null或集合为空,则结果将为null,否则为最大日期

正如您所评论的,您需要一个DateTime,因此您需要对任何空集合或没有带值的项执行某些操作,您可以使用

DateTime biggest=myCollection.Max(r=>r.ExpirationDate) ?? DateTime.MinValue
这将为您提供
DateTime.MinValue
,而不是我上一个示例中的null(它还具有使用
any
子句迭代集合一次的优势)。我选择了
MinValue
作为例子。你可以用你自己的业余约会

使用日期时间?更好,因为它允许您使用null表示它的意思-未定义为
MinValue
可能是列表中的有效项

DateTime? latestDate = myCollection.Max(r => r.ExpirationDate);
Intellisense应该为您提供Max()方法。=)


现在,如果您必须将它分配给DATETIME,我会考虑这样做:

DateTime latestDate = myCollection.Where(r => r.ExpirationDate.HasValue)
                                  .Max(r => r.ExpirationDate)
                                  .Value;
这不包括空集合或仅包含null ExpirationDates的集合的情况


根据您之前的逻辑,检查

myCollection.Any(r => r.ExpirationDate.HasValue)

在尝试分配值之前,可能是一个好主意。

按日期降序排列列表,并取第一个(如有必要,进行投影)


写这篇文章时,我的印象是
Max()
方法只对数字类型(即int、short、decimal等)进行操作。它似乎也适用于
DateTime
对象。因此,这也可以起作用:

var expiredItems = myCollection
    .Where(item => item.ExpirationDate.HasValue);
if (expiredItems.Any())
{
    var latestExpirationDate = expiredItems.Max(item => item.ExpirationDate.Value);
    // do something with latestExpirationDate
}

只需确保在分配
之前进行空引用检查。ExpriationDate

DateTime maxDate = myCollection.OrderByDescending(o => o.ExpirationDate).Take(1).FirstOrDefault().ExpirationDate;
正确的想法

DateTime maxDate = objL.Max(o => o.ExpirationDate);

嘿,我也觉得不错,但是MaxDate()在哪里呢?:)where条件是不必要的,类型也将是DateTime?不是DateTime,因此此代码将出错。先前删除了where条件-错过了DateTime?=)@J.Steen-我想返回一个DateTime(不是DateTime?@ooo-它不仅是空集合,如果您的值都没有过期日期,也会返回。这是不必要的,因为它被投影到第一个日期。first()将抛出一个空集合的异常OK,那又怎样?了不起的事这不是问题中的一个限制,因此我们也不关心。Max()在IComparables上运行。=)@J.Steen:在尝试验证使用
Max()
的解决方案后,我意识到了这一点在使用FirstOrDefault()时,是否需要执行(1)?否。在
DateTime
上永远无法获得空引用异常。DateTime是一种值类型,这意味着它驻留在堆栈上
NullReferenceException
用于引用类型(在堆上)。参见代码:
DateTime dt;Console.WriteLine(dt.ToShortDateString())
Nullable
的工作原理与此相同。@mattmc3-但类型不是DateTime,类型是周围的类,海报表明FirstOrDefault可以返回null,因此,当您访问endMatt上的ExpirationDate属性时,可能会出现null引用异常。如果集合为空,则如果尝试访问.First()上的属性,则会引发null异常。它不是在DateTime上引发的,而是在包含DateTime.Bob的对象上引发的,不,你是对的…我今天早上冲出门,应该放慢速度…如果使用First或FirstOrDefault()则不需要Take(1)。如果集合为空或没有设置ExpirationDate的项目,则需要什么行为?@BobVale如果ExpirationDate是DateTime类型,则每个r都将有一个ExpirationDate。由于DateTime是一个结构,ExpirationDate永远不能为空。@但是如果您查看,OP使用
ExpirationDate.HasValue
ExpirationDate.Value
,指示ExpirationDate的类型为
DateTime?
(即
Nullable
DateTime maxDate = objL.Max(o => o.ExpirationDate);