为什么当用简写形式表示时,此三元语句会返回假肯定?

时间:2018-11-26 20:21:44

标签: c# boolean ternary-operator boolean-expression short-circuiting

我一直在抓狂,因为除了格式之外,这些语句看起来几乎是相同的-但是简写形式似乎评估方式不同,并在不应该返回true时产生误报。

在以下示例中,假设programRecord.Award = 'Emmy'targetAward = 'Oscar'

错误代码给出误报的原因:

private bool MatchMe(string programId, string targetAward, string targetLevel, Program programRecord)
{
    var isMatched = programRecord.Status == "Active"
        && string.IsNullOrEmpty(programId) ? true : programRecord.Pid == programId
        && string.IsNullOrEmpty(targetAward) ? true : programRecord.Award == targetAward
        && string.IsNullOrEmpty(targetLevel) ? true : programRecord.Level == targetLevel;
    return isMatched;
}

好的代码:

    private bool MatchMe(string programId, string targetAward, string targetLevel, Program programRecord)
    {
        var isMatched = programRecord.Status == "Active";
        var isMatched2 = string.IsNullOrEmpty(programId) ? true : programRecord.Pid == programId;
        var isMatched3 = string.IsNullOrEmpty(targetAward) ? true : programRecord.Award == targetAward;
        var isMatched4 = string.IsNullOrEmpty(targetLevel) ? true : programRecord.Level == targetLevel;
        var doIMatch = isMatched && isMatched2 && isMatched3 && isMatched4;
        return doIMatch;
    }

速记版本中引起此问题的原因是什么?我认为一个false值将迫使整个语句返回false,但是缩写版本不会发生这种情况。

3 个答案:

答案 0 :(得分:3)

您比较的格式错误。如果正确解释,实际上您需要使用括号来强制内联。

您应该改为以下内容

private bool MatchMe(string programId, string targetAward, string targetLevel, Program programRecord)
{
    var isMatched = programRecord.Status == "Active"
        && (string.IsNullOrEmpty(programId) ? true : programRecord.Pid == programId)
        && (string.IsNullOrEmpty(targetAward) ? true : programRecord.Award == targetAward)
        && (string.IsNullOrEmpty(targetLevel) ? true : programRecord.Level == targetLevel);
    return isMatched;
}

答案 1 :(得分:1)

三元运算符未按照您所认为的那样进行评估。考虑以下示例:

var val = true ? true : false && false ? false : false;
var val2 = (true ? true : false) && (false ? false : false);
Console.WriteLine(val);
Console.WriteLine(val2);

输出:

True
False

所以您看到,第一个表达式的计算结果为

var val = true ? true : (false && false ? false : false);

答案 2 :(得分:1)

正如其他显示的那样,您需要将三元表达式放在方括号中。原因是&&运算符的优先级高于?:运算符。

请参阅:7.2.1 Operator precedence and associativity