4

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

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

我希望它们是等效的:首先,a?.b评估 的值,然后result.c评估。因此,如果a == null,应该抛出异常。

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

4

2 回答 2

9

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

a?.bc

  1. 返回Evaluate a=> null,鉴于null 条件运算符是 short-circuiting ,不会评估其他任何内容。

(a?.b).c

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

为了使这些情况相同,您应该进行比较

  1. a?.b.c
  2. (a?.b)?.c
  3. a?.b?.c(正如你已经提到的)
于 2018-08-01T19:03:12.003 回答
1

除了 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; }
}
于 2018-08-01T19:30:29.287 回答