使用聚结零操作上可空类型改变隐式类型(using coalescing null operator

2019-06-23 15:45发布

我希望接下来的三行代码是相同的:

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的替换与空合并版本的第二个表达式。

据我所知,更换

somevar != null ? somevar : somedefault;

somevar ?? somedefault;

确实应该产生相同的结果。 但在可空类型隐式类型,编译器似乎威胁?? 仿佛这意味着什么。

somevar != null ? somevar.Value : somedefault;

所以我想我的问题是,为什么当我使用隐式类型发生变化?? ,并且还当文档中我能找到这些信息。

顺便说一句,这不是一个真实的场景,但我想,为什么使用知道?? 改变(隐式)型。

Answer 1:

你的前两个例子带坏你; 更好的是考虑不是你

var dateTimeNullable1 = nullableDateTime.HasValue 
    ? nullableDateTime 
    : DateTime.Now;

反而

var dateTimeNullable1 = nullableDateTime.HasValue 
    ? nullableDateTime.Value 
    : DateTime.Now;

引用部分7.12“空合并操作的” C#3.0规范的(道歉略举步维艰格式):

类型表达a ?? b a ?? b取决于所隐式转换如下类型的操作数之间的可用。 按优先顺序,类型a ?? b a ?? bA 0AB ,其中A是的类型aB是类型b (其中, b具有类型),和A 0是基础类型的A如果A是一个空类型,或A并非如此。

因此,如果aNullable<Something> ,和b可以隐式转换到Something ,整个表达式的类型将是Something 。 作为@Damien_The_Unbeliever表明,该运营商的一点是要凝聚空!



Answer 2:

要全力以赴语言的律师,片刻。 从C#规范(第4版):

7.13

类型表达a ?? b a ?? b取决于其隐式转换都可以在操作数。 按优先顺序,类型a ?? b a ?? bA0AB ,其中A是的类型a (假设a具有类型), B是类型b (其中, b具有类型),并且A0是基础类型的A如果A是一个空类型,或A否则。

所以, ?? 显式定义喜欢的基本类型的第一表现形式的,如果第一个表达式为null的类型。

而从7.14语言(处理?: )只讨论实际类型的xy ,从形式b ? x : y b ? x : y ,并讨论了这两种类型之间的隐式转换。

如果一个隐式转换(第6.1节)从X到Y的存在,但不从Y到X,则Y为条件表达式的类型

由于Nullable(T)定义了从隐式转换TNullable(T)和从只有一个显式的转换Nullable(T)T ,唯一可能的类型的整体表达的是Nullable(T)



文章来源: using coalescing null operator on nullable types changes implicit type