2012-04-16 28 views
12

我希望接下来的三行代码是相同的:使用上可空类型合并空操作改变隐式类型

public static void TestVarCoalescing(DateTime? nullableDateTime) 
{ 
    var dateTimeNullable1 = nullableDateTime.HasValue ? nullableDateTime : DateTime.Now; 
    var dateTimeNullable2 = nullableDateTime != null ? nullableDateTime : DateTime.Now; 
    var dateTimeWhatType = nullableDateTime ?? DateTime.Now; 
} 

在任何情况下,我给你nullableDateTime新变量。我希望所有变量的类型变为DateTime?,因为那是nullableDateTime的类型。但令我惊讶的是,dateTimeWhatType的类型只是DateTime,所以不能为空。

更糟糕的是,ReSharper的建议有一个空合并表达式替换第二份声明,把它变成表达3.所以,如果我让ReSharper的做它的事,变量的类型将改变DateTime?DateTime

事实上,让我们说,在该方法的其余部分,我会用

if (someCondition) dateTimeNullable2 = null; 

这将编译就好了,直到我让ReSharper的与空合并版本替换第二个表达式。

据我所知,有

somevar ?? somedefault; 

更换

somevar != null ? somevar : somedefault; 

的确应该产生相同的结果。但是对于可空类型的隐式键入,编译器似乎威胁??,就好像它意味着。

somevar != null ? somevar.Value : somedefault; 

所以我想我的问题是,为什么当我使用??隐式类型改变,而且在文档中我能找到这些信息。

顺便说一句,这不是一个真实世界的场景,但我想知道为什么使用??更改(隐式)类型。

+3

你为什么期望'nullableDateTime? DateTime.Now'产生一个'DateTime?',当编译器有足够的信息来知道结果永远不会是'null'? – 2012-04-16 08:16:02

+0

@Damien:在我的第一个和第二个例子中,编译器也有足够的信息来知道结果永远不会是null。这正是我发现这种行为有点奇怪的原因。 – comecme 2012-04-16 09:43:59

+1

但是'?:'支持更大范围的可能输入(没有理由'条件'需要连接到任何一个结果'表达式')。因此,将编译器设计为针对“?:”执行此分析是不常见的。而对于'??',它确切知道结果将是第一个表达式,不可能是表达式为空或第二个表达式。 – 2012-04-16 10:00:51

回答

6

你的前两个例子会让你误入歧途;更好的是考虑不是你

var dateTimeNullable1 = nullableDateTime.HasValue 
    ? nullableDateTime 
    : DateTime.Now; 

而是

var dateTimeNullable1 = nullableDateTime.HasValue 
    ? nullableDateTime.Value 
    : DateTime.Now; 

引述部分7.12 “空合并操作的” C#3.0规范的(对于轻微举步维艰格式道歉):

表达式a ?? b的类型取决于哪些隐式 转换是avai在操作数的类型之间进行标记。为了优先 ,的a ?? b类型是A0A,或B, 其中Aa类型,Bb类型(前提是 b具有类型),和A0A的基础类型,如果 A是可以为空的类型,则为A,否则为A

所以如果aNullable<Something>,和b可以隐式转换到Something,整个表达式的类型将是Something。正如@Damien_The_Unbeliever建议的,这个运算符的是合并空值!

+1

到目前为止,我只搜索了[MSDN文档上的'''](http://msdn.microsoft.com/en-us/library/ms173224.aspx)和[使用可空类型](http:// msdn .microsoft.com/EN-US /库/ 2cf62fcy.aspx)。在这些例子中,他们从不使用'var',而是分配一个明确的类型。无论如何,显然'一个?? b'是**不是**与'a!= null完全相同? a:b'当为可空类型时。 – comecme 2012-04-16 09:41:45