我有一个名为EmailMessage的对象,它有一个可以为空的System.DateTime字段,名为Timestamp。在我的C#代码中,我有以下几行:
var TS = EmailMessage.Timestamp == null ? System.DateTime.Now : EmailMessage.Timestamp;
为什么.NET 4会将TS的数据类型推断为System.DateTime?而不是System.DateTime(换句话说,为什么.NET 4认为TS可以为空?)对我而言,TS显然是不可为空的。
提前感谢您的帮助。
答案 0 :(得分:5)
因为C#编译器只是查看DateTime.Now
和EmailMessage.Timestamp
的类型: - )
我会告诉你一件事:我可以打破你的假设。假设有两个主题。一个线程有你的代码,另一个线程有EmailMessage.Timestamp = null
。另一个线程在EmailMessage.Timestamp == null
和TS = EmailMessage.Timestamp
之间执行。休息: - )
我将补充一点,你的代码通常是这样编写的:
var TS = EmailMessage.Timestamp ?? System.DateTime.Now;
使用?? Operator这样编译器知道TS
不可为空。
答案 1 :(得分:2)
如果EmailMessage.Timestamp为Nullable<T>
,那么这是唯一有效的选项。在真实情况下,它变为Nullable<DateTime>
总是有一个值;在假的情况下,它假定Timestamp的值,它可能有也可能没有值。
它没有做任何进一步的分析。但是,您可以使用不可为空的EmailMessage.Timestamp.Value
。
在一般情况下,属性可以在调用之间更改值,因此检查null并假设下次将为null是不安全的。这不会发生在这里,但这就是c#编译器没有做出任何假设的原因。
这里简单的形成可能是:
var ts = EmailMessage.Timestamp ?? DateTime.Now;
答案 2 :(得分:2)
因为存在从DateTime
到DateTime?
的隐式转换(而不是另一种方式,即您执行类似condition ? EmailMessage.TimeStamp : null
的操作。
但是你应该在这里使用null-coalescing运算符:
var TS = EmailMessage.TimeStamp ?? DateTime.Now
答案 3 :(得分:1)
你可能会追求的是这样的事情:
var TS = EmailMessage.TimeStamp == null ? DateTime.Now : EmailMessage.TimeStamp.Value;
或者
var TS = (EmailMessage.TimeStamp ?? DateTime.Now).Value;
答案 4 :(得分:1)
EmailMessage.Timestamp
始终为DateTime?
。如果您之前检查它是否为null无关紧要。编译器不在乎也不应该在意。在多线程应用程序中,EmailMessage.Timestamp
可以在检查和使用值的位置之间进行更改。表单编译器透视图EmailMessage.Timestamp
在以后使用时可以为null,并且应该具有类型DateTime?
。