Почему это троичное выражение возвращает ложные срабатывания в сокращенной записи? - PullRequest
0 голосов
/ 26 ноября 2018

Я почесал голову над этим, поскольку эти выражения кажутся почти идентичными, кроме формата - однако сокращенное, кажется, оценивает по-разному и создает ложные срабатывания, возвращая 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;
    }

Что такоепроисходит в сокращенной версии, которая вызывает это?Я бы подумал, что одно ложное значение заставит весь оператор возвращать ложь, однако этого не происходит с сокращенной версией.

Ответы [ 3 ]

0 голосов
/ 26 ноября 2018

Тернарный оператор оценивается не так, как вы думаете.Рассмотрим следующий пример:

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);
0 голосов
/ 26 ноября 2018

Как показали другие, вам необходимо заключить троичные выражения в скобки.Причина в том, что оператор && имеет более высокий приоритет, чем оператор ?:.

См .: 7.2.1 Приоритет оператора и ассоциативность

0 голосов
/ 26 ноября 2018

Ваш формат не соответствует тому, что вы сравниваете.На самом деле вам нужна скобка для принудительной вставки строки, если она интерпретируется правильно.

вместо нее должно быть следующее

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