我对空条件运算符与常规属性访问如何级联感到困惑。举两个例子:
ANY_NUMBER_SRCH = r"(?P<number_capture>(?P<pre1>(?<![^0-9,.+-])|)(?P<number>(?P<sign_symbol_opt1>(?<![0-9])[+-])?(?P<whole_number_w_thous_sep>(?P<first_group>\d{1,3})(?P<thousands_separator>[ ,])(?P<three_digits_w_sep>(?P<three_digits>\d{3})(?P=thousands_separator))*(?P<last_group_of_three>\d{3})(?!\d)|(?P<whole_number_w_o_thous_sep>\d+))(?P<decimal_separator_1>[.])?(?P<fractional_w_whole_before>(?<=[.])(?P<digits_after_decimal_sep_1>\d+))?(?P<post1>(?<![^0-9,.+-])|)|(?P<pre2>(?<![^0-9,.+-])|)(?P<fractional_without_whole_before>(?P<sign_symbol_opt2>(?<![0-9])[+-])?(?P<decimal_separator_2>[.])(?P<digits_after_decimal_sep_2>\d+)))(?P<post2>(?<![^0-9,.+-])|))"
我希望它们是等效的:首先,评估a?.b.c
(a?.b).c
的值,然后评估a?.b
。因此,如果result.c
,则应引发异常。
但是,这仅在第二个表达式中发生。第一个表达式的计算结果为a == null
,这意味着它与null
相同。 为什么?
答案 0 :(得分:9)
这只是运算符优先级的问题。让我们看一下这些案例:
a?.b.c
a
=> null
,鉴于the null-conditional operators are short-circuiting,没有其他评估。(a?.b).c
a
=>返回null
((B)null).c
=>抛出NullReferenceException
要使这些情况相同,您应该进行比较
a?.b.c
(a?.b)?.c
a?.b?.c
(您已经提到过)答案 1 :(得分: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; }
}