简体   繁体   中英

Why is ReSharper telling me my expression is always true?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM