var a = b?.cd;
这个表达式不应该总是给出编译错误吗?如果 b 为 null,则传播 null 值,因此 c 也将为 null,因此也需要此运算符。据我了解,在表达式中使用此运算符会像病毒一样传播。
但是 Visual Studio 2015 和 Resharper 都没有对我说什么,我在这里错过了什么吗?
var a = b?.cd;
这个表达式不应该总是给出编译错误吗?如果 b 为 null,则传播 null 值,因此 c 也将为 null,因此也需要此运算符。据我了解,在表达式中使用此运算符会像病毒一样传播。
但是 Visual Studio 2015 和 Resharper 都没有对我说什么,我在这里错过了什么吗?
运算符只是这个的语法糖:
MyType a = b == null ?
null:
b.c.d;
我不清楚为什么这会引发编译错误。
如果 b 为 null,则传播 null 值,因此 c 也将为 null,因此也需要此运算符
这不是真的。实际上 when b
is nullc
甚至不存在,因为没有该成员可以存在的实例。因此,简而言之,运算符只是返回null
并省略评估c
甚至d
进一步。
此运算符会短路并在isnull
的情况下返回。b
null
var a = b == null ? null : b.c.d
这就是该语句在旧方式中的样子,?.
当它之前的内容为 null 时,运算符不会看起来更深,它只是返回 null,但是你会在b
定义的地方得到一个错误,但b.c == null
因为你没有写为var a = b?.c?.d
.
注意:
var a1 = b?.c.d;
完全不同于:
var a2 = (b?.c).d;
简而言之,一元运算符的工作原理并不容易解释?.
(是的,一元!)。?.
但想法是,如果之前的表达式为空,则跳过“操作”“链”的其余部分。
因此,对于,只要碰巧为空a1
,您就会得到成员携带的编译时类型的空值d
(或Nullable<>
必要时的该类型) 。b
当b
碰巧为非空时,您会得到与b.c.d
如果b.c
为空可能会失败的结果相同。
但是a2
却大不相同。如果为空,它总是会爆炸b
,因为括号(b?.c)
将是空引用,下一个.
运算符将导致NullReferenceException
. (我假设这里c
在编译时有一个引用类型。)
所以不要认为有一种“左结合性”b?.c.d
等同于(b?.c).d
!
您可以在另一个线程的这个答案中找到初步 C# 语言规范的链接;他们在第 7.7.1 节中提到空条件运算符作为一元运算符。