简体   繁体   English

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

[英]The return type of a C# conditional operator

I have an object called EmailMessage, which has a nullable System.DateTime field called Timestamp. 我有一个名为EmailMessage的对象,它有一个可以为空的System.DateTime字段,名为Timestamp。 In my C# code I have the following line: 在我的C#代码中,我有以下几行:

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

Why does .NET 4 infer the data type of TS to be System.DateTime? 为什么.NET 4推断TS的数据类型是System.DateTime? rather than System.DateTime (In other words, why does .NET 4 think TS is nullable?) It seems really obvious to me that TS is decidedly not nullable. 而不是System.DateTime(换句话说,为什么.NET 4认为TS可以为空?)对我而言,TS显然是不可空的。

Thanks in advance for your help. 在此先感谢您的帮助。

Because the C# compiler simply looks at the types of DateTime.Now and EmailMessage.Timestamp :-) 因为C#编译器只是查看DateTime.NowEmailMessage.Timestamp的类型:-)

And I'll tell you something: I could break your assumption. 我会告诉你一件事:我可以打破你的假设。 Let's say that there are two threads. 假设有两个主题。 One thread has your code, the other thread has EmailMessage.Timestamp = null . 一个线程有你的代码,另一个线程有EmailMessage.Timestamp = null The other thread executes between the EmailMessage.Timestamp == null and the TS = EmailMessage.Timestamp . 另一个线程在EmailMessage.Timestamp == nullTS = EmailMessage.Timestamp之间执行。 Break :-) 休息:-)

I'll add that your code normally is written this way: 我将补充一点,你的代码通常是这样编写的:

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

using the ?? 使用?? Operator This way the compiler knows that TS isn't nullable. 运算符这样编译器就知道TS不可为空。

If EmailMessage.Timestamp is Nullable<T> , then that is the only valid option. 如果EmailMessage.Timestamp是Nullable<T> ,那么这是唯一有效的选项。 In the true case, it becomes a Nullable<DateTime> that always has a value; 在真实情况下,它变为Nullable<DateTime>始终具有值; in the false case it assumes the value of Timestamp, which may or may not have a value. 在假的情况下,它假定Timestamp的值,它可能有也可能没有值。

It does not do any further analysis. 它没有做任何进一步的分析。 You could, however, use EmailMessage.Timestamp.Value , which is non-nullable. 但是,您可以使用不可为空的EmailMessage.Timestamp.Value

In the general case, properties can change value between calls, so it is not safe to check against null and assume it will be null next time. 在一般情况下,属性可以在调用之间更改值,因此检查null并且假设下次将为null是不安全的。 That won't happen here, but that is why the c# compiler doesn't make any assumptions. 这不会发生在这里,但这就是c#编译器没有做出任何假设的原因。

A simple formation here is probably: 这里简单的形成可能是:

var ts = EmailMessage.Timestamp ?? DateTime.Now;

Because there is an implicit conversion from DateTime to DateTime? 因为从DateTimeDateTime?存在隐式转换DateTime? (as opposed to going the other way, where you did something like condition ? EmailMessage.TimeStamp : null . (而不是走另一条路,你做了类似condition ? EmailMessage.TimeStamp : null事情condition ? EmailMessage.TimeStamp : null

But you should be using the null-coalescing operator here anyway: 但是你应该在这里使用null-coalescing运算符:

var TS = EmailMessage.TimeStamp ?? DateTime.Now

What you might be after is something like this instead: 你可能会追求的是这样的事情:

var TS = EmailMessage.TimeStamp == null ? DateTime.Now : EmailMessage.TimeStamp.Value;

or perhaps 也许

var TS = (EmailMessage.TimeStamp ?? DateTime.Now).Value;

EmailMessage.Timestamp is always DateTime? EmailMessage.Timestamp总是DateTime? . It does not matter if you check before if it is null or not. 如果您之前检查它是否为null无关紧要。 The compiler does not care and should not care. 编译器不在乎也不应该在意。 In a multi threaded application EmailMessage.Timestamp can change between the check and where you use the value. 在多线程应用程序中, EmailMessage.Timestamp可以在检查和使用值的位置之间进行更改。 Form a compiler perspective EmailMessage.Timestamp can be null when you use it later and should have the type DateTime? 形成编译器透视图EmailMessage.Timestamp在以后使用时可以为null,并且应该具有DateTime?类型DateTime? .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM