C# 为什么ReSharper告诉我我的表情总是正确的?
我有一个LINQ语句,如果序列为空,它将返回null。我将结果分配到一个可为空的C# 为什么ReSharper告诉我我的表情总是正确的?,c#,linq,C#,Linq,我有一个LINQ语句,如果序列为空,它将返回null。我将结果分配到一个可为空的DateTime。稍后我检查DateTime.HasValue属性,ReSharper告诉我表达式始终为true DateTime? latestUploadDateInBLSO = Documents.Where(d => d.DocumentLinkId == documentLinkId &&
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()
无法处理不可为空元素的空序列。它可以处理空值。@GSergMax
可以处理可为空类型的空序列。它只返回null。它仅在序列本身为null
时抛出。因为这里不需要DefaultIfEmpty
。@CharlesMager不知道有一个.NET小提琴。非常有用的演示。谢谢你指出这一点。@juharr这是真的。在这种情况下,可以删除DefaultIfEmpty
。