【问题标题】:Why does this ternary statement return false positives when in shorthand notation?为什么这个三元语句在简写时会返回误报?
【发布时间】:2019-04-28 12:45:59
【问题描述】:

我一直在摸不着头脑,因为除了格式之外这些语句看起来几乎相同 - 但是速记语句似乎评估不同,并且在不应该返回 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,但是缩写版本不会发生这种情况。

【问题讨论】:

  • 旁注,您可以使用or 逻辑,而不是使用三元运算符。 (string.IsNullOrEmpty(programId) || programRecord.Pid == programId)。看到这是操作顺序的问题,做这个方法会很快突出问题。

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


【解决方案1】:

您的格式与您比较的内容不符。如果要正确解释,您实际上需要括号来强制内联。

你应该有以下代替

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;
}

【讨论】:

    【解决方案2】:

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

    见:7.2.1 Operator precedence and associativity

    【讨论】:

      【解决方案3】:

      三元运算符没有像您想象的那样被评估。考虑以下示例:

      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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-20
        • 1970-01-01
        • 1970-01-01
        • 2023-01-24
        相关资源
        最近更新 更多