C#条件运算符的返回类型

本文关键字:返回类型 条件运算符 | 更新日期: 2023-09-27 18:13:00

我有一个名为EmailMessage的对象,它有一个可为null的System.DateTime字段,名为Timestamp。在我的C#代码中,我有以下行:

var TS = EmailMessage.Timestamp == null ? System.DateTime.Now : EmailMessage.Timestamp;

为什么.NET 4将TS的数据类型推断为System.DateTime?而不是System.DateTime(换句话说,为什么.NET4认为TS可以为null?(对我来说,TS显然是不可以为null的。

提前感谢您的帮助。

C#条件运算符的返回类型

因为C#编译器只查看DateTime.NowEmailMessage.Timestamp的类型:-(

我要告诉你一件事:我可以打破你的假设。假设有两条线索。一个线程包含您的代码,另一个线程则包含EmailMessage.Timestamp = null。另一个线程在EmailMessage.Timestamp == nullTS = EmailMessage.Timestamp之间执行。中断:-(

我要补充的是,你的代码通常是这样写的:

var TS = EmailMessage.Timestamp ?? System.DateTime.Now;

使用??运算符通过这种方式,编译器知道TS不可为null。

如果EmailMessage.Timestamp是Nullable<T>,那么这是唯一有效的选项。在真实的情况下,它变成一个Nullable<DateTime>,它总是有一个值;在false的情况下,它假定Timestamp的值,该值可能有值,也可能没有值。

它没有做任何进一步的分析。但是,您可以使用不可为null的EmailMessage.Timestamp.Value

在一般情况下,属性可以在调用之间更改值,因此检查null并假设下次为null是不安全的。这在这里不会发生,但这就是为什么c编译器不做任何假设。

这里的一个简单形式可能是:

var ts = EmailMessage.Timestamp ?? DateTime.Now;

因为有一个从DateTimeDateTime?的隐式转换(而不是走另一条路,在那里你做了类似condition ? EmailMessage.TimeStamp : null的事情。

但无论如何,您应该在这里使用空合并运算符:

var TS = EmailMessage.TimeStamp ?? DateTime.Now

你可能想要的是这样的东西:

var TS = EmailMessage.TimeStamp == null ? DateTime.Now : EmailMessage.TimeStamp.Value;

或者

var TS = (EmailMessage.TimeStamp ?? DateTime.Now).Value;

EmailMessage.Timestamp始终为DateTime?。如果你之前检查它是否为空,这并不重要。编译器不在乎,也不应该在乎。在多线程应用程序中,EmailMessage.Timestamp可以在检查和使用值的位置之间进行更改。从编译器的角度来看,EmailMessage.Timestamp在以后使用时可以为null,并且应该具有DateTime?类型。