4

var a = b?.cd;

这个表达式不应该总是给出编译错误吗?如果 b 为 null,则传播 null 值,因此 c 也将为 null,因此也需要此运算符。据我了解,在表达式中使用此运算符会像病毒一样传播。

但是 Visual Studio 2015 和 Resharper 都没有对我说什么,我在这里错过了什么吗?

4

4 回答 4

4

运算符只是这个的语法糖:

MyType a = b == null ? 
    null: 
    b.c.d;

我不清楚为什么这会引发编译错误。

如果 b 为 null,则传播 null 值,因此 c 也将为 null,因此也需要此运算符

这不是真的。实际上 when bis nullc甚至不存在,因为没有该成员可以存在的实例。因此,简而言之,运算符只是返回null并省略评估c甚至d进一步。

于 2017-03-31T14:05:06.997 回答
0

此运算符会短路并在isnull的情况下返回。bnull

于 2017-03-31T14:05:08.890 回答
0
var a = b == null ? null : b.c.d

这就是该语句在旧方式中的样子,?.当它之前的内容为 null 时,运算符不会看起来更深,它只是返回 null,但是你会在b定义的地方得到一个错误,但b.c == null因为你没有写为var a = b?.c?.d.

于 2017-03-31T15:39:56.997 回答
0

注意:

var a1 = b?.c.d;

完全不同于:

var a2 = (b?.c).d;

简而言之,一元运算符的工作原理并不容易解释?.(是的,一元!)。?.但想法是,如果之前的表达式为空,则跳过“操作”“链”的其余部分。

因此,对于,只要碰巧为空a1,您就会得到成员携带的编译时类型的空值d(或Nullable<>必要时的该类型) 。bb碰巧为非空时,您会得到与b.c.d如果b.c为空可能会失败的结果相同。

但是a2却大不相同。如果为空,它总是会爆炸b,因为括号(b?.c)将是空引用,下一个.运算符将导致NullReferenceException. (我假设这里c在编译时有一个引用类型。)

所以不要认为有一种“左结合性”b?.c.d等同于(b?.c).d!


您可以在另一个线程的这个答案中找到初步 C# 语言规范的链接;他们在第 7.7.1 节中提到空条件运算符作为一元运算符。

于 2017-03-31T16:02:12.310 回答