我希望接下来的三行代码是相同的:
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用空值合并版本替换第二个表达式为止。据我所知,用空值合并运算符替换原始代码会使ReSharper引发警告。
somevar != null ? somevar : somedefault;
使用
somevar ?? somedefault;
的确应该产生相同的结果。但对于可空类型的隐式类型转换,编译器似乎会将??
视为它的含义。
somevar != null ? somevar.Value : somedefault;
所以我想问的是,为什么使用??
会改变隐式类型,并且在文档中我可以找到关于此的信息在哪里。顺便说一句,这不是一个真实的场景,但我想知道为什么使用??
会改变(隐式)类型。
nullableDateTime ?? DateTime.Now
会产生一个DateTime?
,当编译器已经有足够的信息知道结果永远不会是null
? - Damien_The_Unbeliever?:
支持更广泛的可能输入(condition
不需要与任何一个结果expression
相连)。因此,编译器架构针对?:
执行此分析是不寻常的。而对于??
,它确切地知道结果将是第一个表达式,没有可能该表达式为空,或者是第二个表达式。 - Damien_The_Unbeliever