我有一个方法:
public bool Exists(int levelId, string name, int excludeSubjectIdInCheck = 0)
{
return _context.Subjects.Any(subj => subj.LevelId == levelId
&& String.Equals(subj.Name, name, StringComparison.OrdinalIgnoreCase)
&& subj.DeletedAt == null
&& excludeSubjectIdInCheck != 0 ? subj.Id != excludeSubjectIdInCheck : true);
}
此行评估为true:
subj => subj.LevelId == levelId
这是假的:
String.Equals(subj.Name, name, StringComparison.OrdinalIgnoreCase)
这是真的:
subj.DeletedAt == null
也是如此:
excludeSubjectIdInCheck != 0 ? subj.Id != excludeSubjectIdInCheck : true
但是,此方法返回true。为什么是这样?我希望这会返回false给出3真和1假。但是当我将最后一个条件包装在这样的括号中时:
public bool Exists(int levelId, string name, int excludeSubjectIdInCheck = 0)
{
return _context.Subjects.Any(subj => subj.LevelId == levelId
&& String.Equals(subj.Name, name, StringComparison.OrdinalIgnoreCase)
&& subj.DeletedAt == null
&& (excludeSubjectIdInCheck != 0 ? subj.Id != excludeSubjectIdInCheck : true));
}
返回false。但是,如果我看一下,括号不应该有任何区别,因为它没有将任何条件组合在一起。这段代码中发生了什么?
答案 0 :(得分:3)
三元运算符的优先级最低。没有任何括号,全部
subj.LevelId == levelId
&& String.Equals(subj.Name, name, StringComparison.OrdinalIgnoreCase)
&& subj.DeletedAt == null
&& excludeSubjectIdInCheck != 0
被评估为三元运算符(?:
)的第一个操作数。然后,该值确定要评估的其他两个操作数的哪一部分作为结果。
这里的教训是始终在复杂的布尔表达式中使用括号,以强制进行所需的评估。不要依赖默认优先级以避免出现意外结果。
注意强>
布尔文字作为布尔表达式的操作数几乎总是无关紧要的。我确定有一种方法可以简化你的布尔表达式来完全删除三元运算符。我太累了,不能在此刻思考这一切。我认为它涉及将三元运算符的条件移动到较大表达式的开头。