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

时间:2011-10-30 10:32:43

标签: c# entity-framework nullable

我有一个名为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显然是不可为空的。

提前感谢您的帮助。

5 个答案:

答案 0 :(得分:5)

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

我会告诉你一件事:我可以打破你的假设。假设有两个主题。一个线程有你的代码,另一个线程有EmailMessage.Timestamp = null。另一个线程在EmailMessage.Timestamp == nullTS = 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)

因为存在从DateTimeDateTime?的隐式转换(而不是另一种方式,即您执行类似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?