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#编译器只查看DateTime.Now
和EmailMessage.Timestamp
的类型:-(
我要告诉你一件事:我可以打破你的假设。假设有两条线索。一个线程包含您的代码,另一个线程则包含EmailMessage.Timestamp = null
。另一个线程在EmailMessage.Timestamp == null
和TS = 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;
因为有一个从DateTime
到DateTime?
的隐式转换(而不是走另一条路,在那里你做了类似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?
类型。