在多数情况下,&&
and ||
优先于&
and |
因为前者是短路的,也就是说,一旦结果明确,评估就被取消。
Example:
if(CanExecute() && CanSave())
{
}
If CanExecute
回报false
,完整的表达式将是false
,无论返回值如何CanSave
。因为这,CanSave
没有被执行。
这在以下情况下非常方便:
string value;
if(dict.TryGetValue(key, out value) && value.Contains("test"))
{
// Do Something
}
TryGetValue
回报false
如果在字典中找不到提供的键。由于短路的性质&&
, value.Contains("test")
仅当执行时TryGetValue
回报true
因此value
is not null
。如果您想使用按位与操作员&
相反,你会得到一个NullReferenceException
如果在字典中找不到该键,因为无论如何都会执行表达式的第二部分。
一个类似但更简单的示例是以下代码(如 TJHeuvel 提到的):
if(op != null && op.CanExecute())
{
// Do Something
}
CanExecute
仅在以下情况下执行op
is not null
. If op
is null
,表达式的第一部分(op != null
) 评估为false
以及其余的评价(op.CanExecute()
) 被跳过。
除此之外,从技术上来说,它们也有所不同:
&&
and ||
只能用于bool
然而&
and |
可用于任何整型(bool
, int
, long
, sbyte
, ...),因为它们是按位运算符。&
is the 按位与运算符和|
is the 按位或操作员。
更准确地说,在 C# 中,这些运算符 (&
, |
[and ^
])被称为“逻辑运算符”(参见C# spec,第 7.11 章)。这些运算符有多种实现:
- 对于整数 (
int
, uint
, long
and ulong
,第 7.11.1 章):
它们的实现是为了计算操作数和运算符的按位结果,即&
是计算按位逻辑的实现AND
etc.
- 对于枚举(第 7.11.2 章):
它们被实现来执行枚举的基础类型的逻辑操作。
- 对于 bool 和可为 null 的繁荣(第 7.11.3 和 7.11.4 章):
结果不是使用按位计算来计算的。结果基本上是根据两个操作数的值来查找的,因为可能性的数量很小。
由于这两个值都用于查找,因此此实现不会短路。