使用上可空类型合并空操作改变隐式类型
我希望接下来的三行代码是相同的:使用上可空类型合并空操作改变隐式类型
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;
所以我想我的问题是,为什么当我使用??
隐式类型改变,而且在文档中我能找到这些信息。
顺便说一句,这不是一个真实世界的场景,但我想知道为什么使用??
更改(隐式)类型。
你的前两个例子会让你误入歧途;更好的是考虑不是你
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
类型是A
0
,A
,或B
, 其中A
是a
类型,B
是b
类型(前提是b
具有类型),和A
0
是A
的基础类型,如果A
是可以为空的类型,则为A
,否则为A
。
所以如果a
是Nullable<Something>
,和b
可以隐式转换到Something
,整个表达式的类型将是Something
。正如@Damien_The_Unbeliever建议的,这个运算符的点是合并空值!
到目前为止,我只搜索了[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
你为什么期望'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