我对null条件运算符如何与普通属性访问级联感到困惑。举两个例子:
a?.b.c
(a?.b).c
我希望它们是等价的:首先,对a?.b
的值进行求值,然后对result.c
进行求值。因此,如果是a == null
,则应该抛出异常。
然而,这种情况只发生在第二个表达式中。第一个表达式的计算结果为null
,这意味着它与a?.b?.c
相同为什么
这只是运算符优先级的问题。让我们来看看案例:
a?。b.c
- Evaluate
a
=>返回null
,如果空条件运算符短路,则不计算其他值
(a?.b(.c
- 评估
a
=>返回null
- Evaluate
((B)null).c
=>抛出NullReferenceException
为了使这些情况等效,您应该比较
a?.b.c
(a?.b)?.c
a?.b?.c
(正如您已经提到的(
除了Camilo已经提供的内容之外,我不知道这是否有帮助,但这里有一个简短的比较,显示了在没有null条件运算符的情况下逻辑的外观。
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; }
}