空条件运算符
Null-Conditional Operator
var a = b?.c.d;
这个表达式不应该总是给出编译错误吗?如果 b 为 null,则通过 null 值传播,因此 c 也将为 null,因此也需要此运算符。据我了解,在表达式中使用此运算符传播病毒。
但是 Visual Studio 2015 和 Resharper 都没有对我说什么,我是不是漏掉了什么?
运算符只是语法糖:
MyType a = b == null ?
null:
b.c.d;
我不清楚为什么这会引发编译错误。
If b is null, the null value is propagated through so c will also be null and thus also need this operator
这不是真的。实际上,当 b
为空时,c
甚至不存在,因为没有该成员可以存在的实例。所以简而言之,运算符只是 returns null
并且省略了 c
甚至 d
的进一步评估。
此运算符短路并且 returns null
如果 b
是 null
。
var a = b == null ? null : b.c.d
这就是该语句以旧方式看起来的样子,?.
运算符在它之前的内容为 null 时不会看得更深,它只是 returns null,但是你会在定义 b
但 b.c == null
的地方出现错误,因为你没有写成 var a = b?.c?.d
.
注意:
var a1 = b?.c.d;
完全不同于:
var a2 = (b?.c).d;
简而言之,要解释一元运算符 ?.
的工作原理并不是很容易(是的,一元!)。但想法是,如果 ?.
之前的表达式为空,则跳过 "operations" 的 "chain" 的其余部分。
所以对于 a1
,每当 b
时,您都会得到成员 d
携带的编译时类型的空值(或 Nullable<>
,如果需要的话)恰好为空。当 b
恰好为非空时,您将得到与 b.c.d
相同的结果,如果 b.c
为空,则可能会失败。
但是a2
就完全不同了。如果 b
为空,它总是会爆炸,因为括号 (b?.c)
将是一个空引用,而下一个 .
运算符将导致 NullReferenceException
。 (我在这里假设 c
在编译时有一个引用类型。)
所以不要认为有一种"left-associativity"使得b?.c.d
等同于(b?.c).d
!
您可以在 中找到初步 C# 语言规范的 link;他们在 § 7.7.1.
中提到 Null-conditional operator 作为一元运算符
var a = b?.c.d;
这个表达式不应该总是给出编译错误吗?如果 b 为 null,则通过 null 值传播,因此 c 也将为 null,因此也需要此运算符。据我了解,在表达式中使用此运算符传播病毒。
但是 Visual Studio 2015 和 Resharper 都没有对我说什么,我是不是漏掉了什么?
运算符只是语法糖:
MyType a = b == null ?
null:
b.c.d;
我不清楚为什么这会引发编译错误。
If b is null, the null value is propagated through so c will also be null and thus also need this operator
这不是真的。实际上,当 b
为空时,c
甚至不存在,因为没有该成员可以存在的实例。所以简而言之,运算符只是 returns null
并且省略了 c
甚至 d
的进一步评估。
此运算符短路并且 returns null
如果 b
是 null
。
var a = b == null ? null : b.c.d
这就是该语句以旧方式看起来的样子,?.
运算符在它之前的内容为 null 时不会看得更深,它只是 returns null,但是你会在定义 b
但 b.c == null
的地方出现错误,因为你没有写成 var a = b?.c?.d
.
注意:
var a1 = b?.c.d;
完全不同于:
var a2 = (b?.c).d;
简而言之,要解释一元运算符 ?.
的工作原理并不是很容易(是的,一元!)。但想法是,如果 ?.
之前的表达式为空,则跳过 "operations" 的 "chain" 的其余部分。
所以对于 a1
,每当 b
时,您都会得到成员 d
携带的编译时类型的空值(或 Nullable<>
,如果需要的话)恰好为空。当 b
恰好为非空时,您将得到与 b.c.d
相同的结果,如果 b.c
为空,则可能会失败。
但是a2
就完全不同了。如果 b
为空,它总是会爆炸,因为括号 (b?.c)
将是一个空引用,而下一个 .
运算符将导致 NullReferenceException
。 (我在这里假设 c
在编译时有一个引用类型。)
所以不要认为有一种"left-associativity"使得b?.c.d
等同于(b?.c).d
!
您可以在