[英]Why does the null-conditional operator change regular property access?
I'm confused about how the null-conditional operator cascades with normal property access. 我很困惑null条件运算符如何与普通属性访问级联。 Take these two examples:
拿这两个例子:
a?.b.c
(a?.b).c
I would expect them to be equivalent: first, the value of a?.b
is evaluated, then result.c
is evaluated. 我希望它们是等价的:首先,评估
a?.b
的值,然后评估result.c
。 Thus if a == null
, an exception should be thrown. 因此,如果
a == null
,则应抛出异常。
However, that only happens in the second expression. 但是,这只发生在第二个表达式中。 The first expression evaluates to
null
, meaning it's the same as a?.b?.c
. 第一个表达式的计算结果为
null
,这意味着它与a?.b?.c
。 Why? 为什么?
That's only a matter of operator precedence. 这只是运营商优先权的问题。 Let's go through the cases:
让我们来看看案例:
a?.bc
一个?.BC
a
=> null
is returned, nothing else is evaluated given that the null-conditional operators are short-circuiting . a
=> null
,假设空条件运算符短路,则不评估任何其他值。 (a?.b).c
(一?.B).C
a
=> null
is returned a
=> null
返回 ((B)null).c
=> NullReferenceException
is thrown ((B)null).c
=>抛出NullReferenceException
For these cases to be equivalent, you should be comparing 对于这些相同的情况,您应该进行比较
a?.bc
(a?.b)?.c
a?.b?.c
(as you already mentioned) a?.b?.c
(如你所说) I don't know if this'll help or not, beyond what Camilo already provided, but here's a brief comparison showing how the logic might look without the null-conditional operator in play. 我不知道这是否有所帮助,超出了Camilo已经提供的内容,但是这里有一个简短的比较,显示逻辑在没有空条件运算符的情况下可能看起来如何。
public class Program
{
public static void Main()
{
A a;
a = new A { b = new B { c = 5 } };
Console.WriteLine(a?.b.c); // returns 5;
Console.WriteLine((a?.b).c); // returns 5;
a = null;
Console.WriteLine(a?.b.c ?? -1); // returns -1;
Console.WriteLine((a?.b).c); // throws NullReferenceException
// Similar to a?.b.c
if (a != null)
Console.WriteLine(a.b.c); // returns 5;
else
Console.WriteLine(-1); // returns -1;
// Similar to (a?.b).c
B tmp;
if (a != null)
tmp = a.b;
else
tmp = null;
Console.WriteLine(tmp.c); // returns 5 or throws NullReferenceException
}
}
public class A
{
public B b { get; set; }
}
public class B
{
public int c { get; set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.