using coalescing null operator on nullable types changes implicit type
我希望接下来的三行代码是相同的:
1 2 3 4 5 6 | 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; } |
在所有情况下,我都将
更糟的是,resharper建议用一个空合并表达式替换第二个语句,将其转换为表达式3。所以如果我让resharper做它的事情,变量的类型将从
实际上,假设在方法的其余部分中,我将使用
1 | if (someCondition) dateTimeNullable2 = null; |
在我让resharper用空合并版本替换第二个表达式之前,这将编译得很好。
Afaik,更换
1 | somevar != null ? somevar : somedefault; |
具有
1 | somevar ?? somedefault; |
确实应该产生相同的结果。但对于可以为空的类型的隐式键入,编译器似乎威胁到
1 | somevar != null ? somevar.Value : somedefault; |
所以我想我的问题是,当我使用
顺便说一句,这不是真实的场景,但我想知道为什么使用
你的前两个例子让你误入歧途;最好不要考虑你的
1 2 3 | var dateTimeNullable1 = nullableDateTime.HasValue ? nullableDateTime : DateTime.Now; |
而是
1 2 3 | var dateTimeNullable1 = nullableDateTime.HasValue ? nullableDateTime.Value : DateTime.Now; |
引用C 3.0规范的第7.12节"空合并运算符"(对稍微不正确的格式表示歉意):
The type of the expression
a ?? b depends on which implicit
conversions are available between the types of the operands. In order
of preference, the type ofa ?? b isA 0 ,A , orB ,
whereA is the type ofa ,B is the type ofb (provided that
b has a type), andA 0 is the underlying type ofA if
A is a nullable type, orA otherwise.
因此,如果
去做语言律师,一会儿。根据C规范(第4版):
7.13
The type of the expression
a ?? b depends on which implicit conversions are available on the operands. In order of preference, the type ofa ?? b isA0 ,A , orB , whereA is the type ofa (provided thata has a type),B is the type ofb (provided thatb has a type), andA0 is the underlying type ofA ifA is a nullable type, orA otherwise.
因此,如果第一个表达式是可以为空的类型,那么
而7.14的语言(处理
If an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression
由于