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

C#条件运算符的返回类型,c#,entity-framework,nullable,C#,Entity Framework,Nullable,我有一个名为EmailMessage的对象,它有一个名为Timestamp的可空System.DateTime字段。在我的C#代码中,我有以下行: var TS = EmailMessage.Timestamp == null ? System.DateTime.Now : EmailMessage.Timestamp; 为什么.NET 4推断TS的数据类型为System.DateTime?而不是System.DateTime(换句话说,为什么.NET4认为TS是可空的?),对我来说,TS显然

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

var TS = EmailMessage.Timestamp == null ? System.DateTime.Now : EmailMessage.Timestamp;
为什么.NET 4推断TS的数据类型为System.DateTime?而不是System.DateTime(换句话说,为什么.NET4认为TS是可空的?),对我来说,TS显然是不可空的

提前感谢您的帮助。

因为C#编译器只需查看
DateTime.Now
EmailMessage.Timestamp
:-)

我要告诉你:我可以打破你的假设。假设有两个线程。一个线程有您的代码,另一个线程有
EmailMessage.Timestamp=null
。另一个线程在
EmailMessage.Timestamp==null
TS=EmailMessage.Timestamp
之间执行。中断:-)

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

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

使用这种方法,编译器知道
TS
不可为空。

如果EmailMessage.Timestamp是
null
,那么这是唯一有效的选项。在真实情况下,它将成为始终具有值的
可为空的
;如果为false,则假定Timestamp的值,该值可能有值,也可能没有值

它没有做任何进一步的分析。但是,您可以使用不可为空的
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?
。您之前是否检查它是否为null并不重要。编译器不关心,也不应该关心。在多线程应用程序中
EmailMessage.Timestamp
可以在检查和使用值的位置之间更改。形成编译器透视图
EmailMemessage.Timestamp
在以后使用时可以为空,并且应具有类型
DateTime?

“在false情况下,它假定Timestamp的值,该值可能有值,也可能没有值”–不,时间戳总是有一个值。我认为你的第一段可能是错误的。@阿尔宾,这取决于EmailMessage是什么-变量、字段、属性等-但是的,你是right@Konrad就编译器而言,它可能是也可能不是(它可以为null)非常清楚的解释。感谢您提供有关空合并运算符的指针。感谢您提及空合并运算符。