C# 为什么ReSharper告诉我我的表情总是正确的?

C# 为什么ReSharper告诉我我的表情总是正确的?,c#,linq,C#,Linq,我有一个LINQ语句,如果序列为空,它将返回null。我将结果分配到一个可为空的DateTime。稍后我检查DateTime.HasValue属性,ReSharper告诉我表达式始终为true DateTime? latestUploadDateInBLSO = Documents.Where(d => d.DocumentLinkId == documentLinkId &&

我有一个LINQ语句,如果序列为空,它将返回null。我将结果分配到一个可为空的
DateTime
。稍后我检查
DateTime.HasValue
属性,ReSharper告诉我表达式始终为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;
                }
DateTime?latestUploadDateInBLSO=Documents。其中(d=>d.DocumentLinkId==DocumentLinkId&&
d、 UploadedStage.StageNumber==6&&
d、 DocumentOwnerTeam.TeamId==AuthorUser.Team.TeamId)
.Select(d=>d.uploadendate)
.DefaultIfEmpty()
.Max();
如果(latestUploadDateInBLSO.HasValue){//d.DocumentLinkId==DocumentLinkId&&
d、 UploadedOnDate==latestUploadDateInBLSO&&
d、 UploadedStage.StageNumber==6&&
d、 DocumentOwnerTeam.TeamId==AuthorUser.Team.TeamId).IsLatestVersion=true;
}

既然
latestUploadDateInBLSO
可以为空,那么该表达式如何始终为真?

这是因为
DefaultIfEmpty
调用与一系列不可为空的元素(
DateTime
)相结合-您的意思是从
Where
Select
返回的集合是否为空,而是返回一个集合,其中包含一个默认的
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();
List l=新列表();
DateTime x=l.DefaultIfEmpty().Max();
x、 Dump();
var y=新的日期时间();
y、 Dump();
l、 DefaultIfEmpty().Dump();

如果UploadeNode也是日期时间类型,则它不为空。DateTime的默认值等于DateTime.MinValue。这就是为什么你的nullable总是有一个值。如果要更改此值,您必须明确地说通过DefaultIfEmpty并将NULL作为默认值返回。

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

由于
uploadendate
不可为空,因此结果将始终为
DateTime
值,且从不为空。如果列表为空,您将获得
default(DateTime)
,即
DateTime.MinValue

如果希望它返回
null
,则需要将
uploadendate
转换为
DateTime?
。您可以省略
DefaultIfEmpty
,因为如果类型可为空,则对于空序列,
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();

这两个语句之间有代码吗?上载数据的类型是什么?否,它们是顺序上载数据的类型是什么?在if语句之前,请在latestUploadDateInBLSO.value上尝试Console.WriteLine命令,查看它是否引发InvalidOperationException或使用try-and-catch-on。value@Legion在这种情况下,您的查询将始终返回一个不可为空的
DateTime
,因此结果永远不会为null。这不仅仅是因为
DefaultIfEmpty
调用,而是因为
DefaultIfEmpty
调用了一个不可为null的属性。如果序列为空,我只是试图避免Max出现null引用异常。如果我将
uploadendate
转换为
DateTime?
我不是要回到我开始的地方吗?@Legion如果这样做,你会得到一个
null
值,是的-请看。@juharr如果序列是可为null的元素,它会返回。如果序列由不可为空的元素组成,并且为空,
Max()
抛出
invalidoOperationException
@GSerg您是对的。我没有在文档中查找正确的重载。我的印象是,
Max()
如果为空,将抛出异常。我基本上是在尝试获取最大值(如果存在),如果序列为空则获取null。@Legion空序列与null或null序列不同
Max()
无法处理不可为空元素的空序列。它可以处理空值。@GSerg
Max
可以处理可为空类型的空序列。它只返回null。它仅在序列本身为
null
时抛出。因为这里不需要
DefaultIfEmpty
。@CharlesMager不知道有一个.NET小提琴。非常有用的演示。谢谢你指出这一点。@juharr这是真的。在这种情况下,可以删除
DefaultIfEmpty