我希望接下来的三行代码是相同的:
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用空合并版本替换第二个表达式 .
AFAIK,取代
somevar != null ? somevar : somedefault;
同
somevar ?? somedefault;
应该确实产生相同的结果 . 但是对于可空类型的隐式类型,编译器似乎威胁 ??
,就好像它意味着一样 .
somevar != null ? somevar.Value : somedefault;
所以我想我的问题是为什么当我使用 ??
时隐式类型被更改,而且在文档中我可以找到关于此的信息 .
顺便说一句,这不是一个现实世界的场景,但我想知道为什么使用 ??
更改(隐式)类型 .
2 回答
一时间去找所有语言律师 . 从C#规范(版本4):
因此,如果第一个表达式是可空类型,则
??
被明确定义为首选表达式的基础类型 .而 7.14 (处理
?:
)中的语言仅从b ? x : y
形式讨论了x
和y
的实际类型,并讨论了这两种类型之间的隐式转换 .由于Nullable(T)定义了从
T
到Nullable(T)
的隐式转换,并且只有从Nullable(T)
到T
的显式转换,因此整个表达式中唯一可能的类型是Nullable(T)
.你的前两个例子让你误入歧途;更好的是不要考虑你的
反而
引用C#3.0规范的第7.12节“空合并运算符”(略微粗略格式化的道歉):
因此,如果
a
是Nullable<Something>
,并且b
可以隐式转换为Something
,则整个表达式的类型将为Something
. 正如@Damien_The_Unbeliever建议的那样,这个运算符的意思是合并空值!