在可空类型上使用coalescing null运算符更改隐式类型
我希望接下来的三行代码是相同的:
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
是可空类型,则A
0
是A
的基础类型,或者否则。
因此,如果a
是Nullable
,并且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中的语言(处理?:
:)只讨论了forms为b ? x : y
的x
和y
的实际类型b ? x : y
b ? x : y
,并讨论这两种类型之间的隐式转换。
如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型
由于Nullable(T)
定义了从T
到Nullable(T)
的隐式转换,并且只有从Nullable(T)
到T
的显式转换,因此整个表达式中唯一可能的类型是Nullable(T)
。