2016-04-20 82 views
0

我有这个LINQ语句,如果序列为空,它将返回null。我将结果分配为可空的DateTime。后来我检查DateTime.HasValue属性和ReSharper是否告诉我表达式总是正确的。为什么ReSharper告诉我我的表情永远是真的?

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; 
       } 

由于latestUploadDateInBLSO可以为null,该表达式总是如此?

+3

这两个语句之间是否存在任何代码? UploadedOnDate的类型是什么? –

+0

不,它们是连续的 – Legion

+3

'UploadedOnDate'的类型是什么? –

回答

5

由于UploadedOnDate不为空,结果将始终为DateTime值并且从不为空。如果列表为空,则会得到default(DateTime),即DateTime.MinValue

如果您想要它返回null,您需要将UploadedOnDate转换为DateTime?。您可以省略DefaultIfEmpty根据the docs如果类型为空,则Max将返回null空序列。

DateTime? latestUploadDateInBLSO = Documents 
    .Where(d => d.DocumentLinkId == documentLinkId && d.UploadedInStage.StageNumber == 6 && d.DocumentOwnerTeam.TeamId == AuthorUser.Team.TeamId) 
    .Select(d => (DateTime?)d.UploadedOnDate) 
    .Max(); 
+0

我的印象是Max()会抛出一个异常,如果是null。我基本上试图得到最大值,如果存在,如果序列为空,则为null。 – Legion

+0

@Legion空序列与null或空序列不同。 Max()不能处理不可空元素的空序列。它可以处理空值。 – GSerg

+0

你可以试试它。 [这个小提琴](https://dotnetfiddle.net/1lVxDg)没有。 –

2

这是因为DefaultIfEmpty电话与非空的元素(DateTime)的序列相结合的 - 你说,如果集合从WhereSelect是空的返回,以代替返回集合与内单违约DateTime它,所以它永远不会返回null

这里的一个小样品与从LINQPad输出:

List<DateTime> l = new List<DateTime>(); 
DateTime x = l.DefaultIfEmpty().Max(); 
x.Dump(); 

var y = new DateTime(); 
y.Dump(); 

l.DefaultIfEmpty().Dump(); 

enter image description here

+1

由于'DefaultIfEmpty'调用不是*只是*,这是因为对不可空的属性的'DefaultIfEmpty'调用。 – GSerg

+0

@GSerg公平点,编辑 –

+0

我真的只是试图避免与Max的空引用异常,如果序列是空的。如果我将'UploadedOnDate'转换为'DateTime?'我不会回到我开始的地方吗? – Legion

3

如果uploadedOnDate也是DateTime类型的,则它不会NULL。 DateTime的默认值等于DateTime.MinValue。这就是为什么你的可空值将始终有价值。如果你想改变它,你将明确地通过DefaultIfEmpty来说,并返回NULL作为默认值。

1

DefaultIfEmpty可能将您的DateTime对象初始化为其默认值DateTime.MinValue,因此它永远不会为null,因此HasValue将始终返回true。

相关问题