var a = b?.c.d;
这个表达式不应该总是会出现编译错误吗?如果b为null,则null值会传播,因此c也将为null,并且还需要使用此运算符。在我的理解中,表达式中使用此运算符会产生传染性。
但是,无论是Visual Studio 2015还是Resharper都没有提示任何信息,我是否漏掉了什么?
var a = b?.c.d;
这个表达式不应该总是会出现编译错误吗?如果b为null,则null值会传播,因此c也将为null,并且还需要使用此运算符。在我的理解中,表达式中使用此运算符会产生传染性。
但是,无论是Visual Studio 2015还是Resharper都没有提示任何信息,我是否漏掉了什么?
MyType a = b == null ?
null:
b.c.d;
我不清楚为什么这会导致编译错误。
如果 b 为 null,则 null 值会通过,因此 c 也将为 null,并且因此需要此运算符。
这并不是真的。实际上,当 b
为 null 时,c
甚至不存在,因为没有实例可以存在该成员。因此,简而言之,运算符只返回 null
,并省略进一步评估 c
或甚至 d
。
a
总是被赋予一个新值,尽管这个值可能是null
。 - Servyvar a = (b == null) ? null : b.c.d;
- Jeroen van Langenb
并没有被多次计算,所以你的语法糖也不正确,尽管现在更接近了。 - Servyb
被定义为以下内容:class CurrentClass { static bool wasCalledBefore; static B { get { if(wasCalledBefore) { return null; } wasCalledBefore = true; return new B { c = new C { d = new D(), }, }; } } }
- Jeppe Stig Nielsenvar a1 = b?.c.d;
与之完全不同:
var a2 = (b?.c).d;
很难简短地解释一元运算符?.
的工作原理(是的,一元的!)。但是它的思想是,如果?.
之前的表达式为null,则“操作”链的其余部分都会被跳过。
因此对于a1
,每当b
恰好为null时,您将得到由成员d
(或必要时该类型的Nullable<>
)携带的编译时类型的null。当b
非null时,您将得到与b.c.d
相同的结果,如果b.c
为null可能会失败。
但是a2
则完全不同。如果b
为null,则它将始终崩溃,因为括号(b?.c)
将是一个null引用,接下来的.
运算符将导致NullReferenceException
。(我在这里假设c
在编译时具有引用类型。)
因此,请不要认为存在一种“左关联性”,使b?.c.d
等价于(b?.c).d
!
您可以在另一个线程的此答案中找到初步的C#语言规范链接;它们在§ 7.7.1中将Null-conditional operator作为一元运算符进行了提及。
这个运算符进行短路操作,如果 b
为 null
,则返回 null
。
var a = b == null ? null : b.c.d
这是旧方式中该语句的样子,?.
操作符在它前面的内容为 null 时不会继续往下查找,而是直接返回 null。但是当 b
被定义且 b.c == null
时,如果你没有按照 var a = b?.c?.d
的方式编写,你将会遇到错误。
b
已经是null,c
根本不会被评估,使得a
变成了简单的null
。 - MakePeaceGreatAgainb
是null
,那么表达式不会再被评估,但会产生null
,所以c
不会受到任何影响。 - Codorvar a = (b?.c).d;
这个代码? - Damien_The_Unbeliever