C#条件运算符的返回类型
我有一个名为EmailMessage的对象,它有一个名为Timestamp的可空System.DateTime字段。在我的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显然
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)非常清楚的解释。感谢您提供有关空合并运算符的指针。感谢您提及空合并运算符。