我希望接下来的三行代码是相同的:使用上可空类型合并空操作改变隐式类型
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;
所以我想我的问题是,为什么当我使用??
隐式类型改变,而且在文档中我能找到这些信息。
顺便说一句,这不是一个真实世界的场景,但我想知道为什么使用??
更改(隐式)类型。
你为什么期望'nullableDateTime? DateTime.Now'产生一个'DateTime?',当编译器有足够的信息来知道结果永远不会是'null'? – 2012-04-16 08:16:02
@Damien:在我的第一个和第二个例子中,编译器也有足够的信息来知道结果永远不会是null。这正是我发现这种行为有点奇怪的原因。 – comecme 2012-04-16 09:43:59
但是'?:'支持更大范围的可能输入(没有理由'条件'需要连接到任何一个结果'表达式')。因此,将编译器设计为针对“?:”执行此分析是不常见的。而对于'??',它确切知道结果将是第一个表达式,不可能是表达式为空或第二个表达式。 – 2012-04-16 10:00:51