在可空类型上使用合并空操作符会改变隐式类型
我期望接下来的三行代码是一样的:
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?
到DateTime
。
事实上,让我们假设在该方法的其余部分中,我会使用它
if (someCondition) dateTimeNullable2 = null;
这将编译得很好,直到我让ReSharper用空合并版本替换第二个表达式。
AFAIK,取代
somevar != null ? somevar : somedefault;
同
somevar ?? somedefault;
应该确实产生相同的结果。 但是对于可空类型的隐式输入,编译器似乎会威胁??
就好像它的意思。
somevar != null ? somevar.Value : somedefault;
所以我想我的问题是为什么当我使用隐式类型改变??
,以及在文档中我可以找到有关这方面的信息。
顺便说一句,这不是一个真实的世界情景,但我想知道为什么使用??
更改(隐式)类型。
你的前两个例子会让你误入歧途。 更好的是考虑不是你的
var dateTimeNullable1 = nullableDateTime.HasValue
? nullableDateTime
: DateTime.Now;
反而
var dateTimeNullable1 = nullableDateTime.HasValue
? nullableDateTime.Value
: DateTime.Now;
引用C#3.0规范中的第7.12节“空合并运算符”(对于稍微格式化的道歉):
类型表达a ?? b
a ?? b
取决于操作数类型之间的哪些隐式转换可用。 按优先顺序,类型a ?? b
a ?? b
是A
0
, A
或B
,其中A
是的类型a
, B
是类型b
(其中, b
具有类型),和A
0
是基础类型的A
如果A
是一个空类型,或A
并非如此。
因此,如果a
是Nullable<Something>
,并且b
可以隐式转换为Something
,那么整个表达式的类型将是Something
。 正如@Damien_The_Unbeliever建议的那样,这个运营商的重点是合并空值!
去一切语言律师,一会儿。 从C#规范(版本4):
7.13
类型表达a ?? b
a ?? b
取决于哪些隐式转换可用于操作数。 按优先顺序,类型a ?? b
a ?? b
是A0
, A
或B
,其中A
是的类型a
(假设a
具有类型), B
是类型b
(其中, b
具有类型),并且A0
是基础类型的A
如果A
是可空类型,否则为A
所以, ??
明确定义为首选表达式的基础类型,如果该第一个表达式是可为空的类型。
而从7.14 (处理?:
:)的语言只讨论x
和y
的实际类型,从形式b ? x : y
b ? x : y
,并讨论这两种类型之间的隐式转换。
如果存在从X到Y而不是从Y到X的隐式转换(第6.1节),则Y是条件表达式的类型
由于Nullable(T)
定义了从T
到Nullable(T)
的隐式转换,并且仅从Nullable(T)
到T
的显式转换,整个表达式的唯一可能类型是Nullable(T)
。
上一篇: using coalescing null operator on nullable types changes implicit type