为什么null条件运算符更改常规属性访问



我对null条件运算符如何与普通属性访问级联感到困惑。举两个例子:

a?.b.c
(a?.b).c

我希望它们是等价的:首先,对a?.b的值进行求值,然后对result.c进行求值。因此,如果是a == null,则应该抛出异常。

然而,这种情况只发生在第二个表达式中。第一个表达式的计算结果为null,这意味着它与a?.b?.c相同为什么

这只是运算符优先级的问题。让我们来看看案例:

a?。b.c

  1. Evaluatea=>返回null,如果空条件运算符短路,则不计算其他值

(a?.b(.c

  1. 评估a=>返回null
  2. Evaluate((B)null).c=>抛出NullReferenceException

为了使这些情况等效,您应该比较

  1. a?.b.c
  2. (a?.b)?.c
  3. 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; }
}

最新更新