I have this LINQ statement which returns null if the sequence is empty. I assign the result into a nullable DateTime
. Later on I check if the DateTime.HasValue
property and ReSharper tells me the expression is always true.
DateTime? latestUploadDateInBLSO = Documents.Where(d => d.DocumentLinkId == documentLinkId &&
d.UploadedInStage.StageNumber == 6 &&
d.DocumentOwnerTeam.TeamId == AuthorUser.Team.TeamId)
.Select(d => d.UploadedOnDate)
.DefaultIfEmpty()
.Max();
if (latestUploadDateInBLSO.HasValue) { // <-- Says this is always true
Documents.Single(d => d.DocumentLinkId == documentLinkId &&
d.UploadedOnDate == latestUploadDateInBLSO &&
d.UploadedInStage.StageNumber == 6 &&
d.DocumentOwnerTeam.TeamId == AuthorUser.Team.TeamId).IsLatestVersion = true;
}
Since latestUploadDateInBLSO
can be null, how is that expression always true?
As UploadedOnDate
isn't nullable, the result will always be a DateTime
value and never null. If the list is empty, you'll get default(DateTime)
, which is DateTime.MinValue
.
If you want it to return null
, you'll need to cast your UploadedOnDate
to DateTime?
. You can omit the DefaultIfEmpty
as per the docs Max
will return null
for an empty sequence if the type is nullable.
DateTime? latestUploadDateInBLSO = Documents
.Where(d => d.DocumentLinkId == documentLinkId && d.UploadedInStage.StageNumber == 6 && d.DocumentOwnerTeam.TeamId == AuthorUser.Team.TeamId)
.Select(d => (DateTime?)d.UploadedOnDate)
.Max();
If uploadedOnDate is also of DateTime type then it's not NULL. The default value for DateTime is equal to DateTime.MinValue. That is why your nullable will always have a value. If you want to change this you'll explicitly have to say via DefaultIfEmpty and return NULL as default value.
It's because of the DefaultIfEmpty
call combined with a sequence of non-nullable elements ( DateTime
) - you're saying if the collection returned from the Where
and Select
is empty, to instead return a collection with a single defaulted DateTime
within it, so it will never return null
.
Here's a small sample with the output from LINQPad:
List<DateTime> l = new List<DateTime>();
DateTime x = l.DefaultIfEmpty().Max();
x.Dump();
var y = new DateTime();
y.Dump();
l.DefaultIfEmpty().Dump();
DefaultIfEmpty可能会将DateTime对象初始化为其默认值DateTime.MinValue,因此它永远不会为null,因此HasValue将始终返回true。
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.