Null Check 结合三元表达式抛出 NullReferenceException

Null Check combined with Ternary Expression throws NullReferenceException

我有以下对象:

class Parent
{
    public Child Child { get; set; }
}

class Child
{
    public string Type { get; set; }
    public int Value { get; set; }
}

为什么下面的代码会抛出 NullReferenceException?

var value = parent.Child != null && 
            parent.Child.Type == "test" 
                ? parent.Child.Value == 1 
                : parent.Child.Value == 2;

我认为空检查会阻止条件的第二部分执行。 但是以下代码有效:

var value = (parent.Child != null) && 
            (parent.Child.Type == "test" 
                ? parent.Child.Value == 1 
                : parent.Child.Value == 2);

所以我认为这里有些运算符优先级有问题...

为什么它不抛出 NullReferenceException

var value = parent.Child != null && 
    parent.Child.Type == "test" 
        ? parent.Child.Value == 1 
        : parent.Child.Value == 2;

让我们用临时变量重写您的代码:

bool condition = parent.Child != null && parent.Child.Type == "test";
var value = condition ? parent.Child.Value == 1 : parent.child.Value == 2;

然后用 if 语句使它更清楚:

bool value = false;
bool condition = parent.Child != null && parent.Child.Type == "test";
if (condition)
{
    value = parent.Child.Value == 1;
}
else
{
    vaue = parent.Child.Value == 2;
}

您的条件需要满足两个条件:parent.Child 不为空,并且 parent.Child.Type 等于 "test"。

如果条件为假,则使用三元运算符的 "else" 部分:parent.Child.Value == 2.

如果您的条件因 parent.Child == null 而为假,那么您将尝试在 else 部分访问 null 对象的 属性,从而触发 NullReferenceException.

至于为什么按此顺序解释,请参阅 this documentation page 关于 C# 运算符及其优先级。如您所见,a && b 的优先级高于 a ? b : c。因此 a && b 将在 a ? b : c.

之前执行