布尔逻辑运算符 - AND、OR、NOT、XOR
逻辑布尔运算符使用 bool 操作数执行逻辑运算。 运算符包括一元逻辑非 (!
)、二元逻辑 AND (&
)、OR (|
) 以及异或 (^
),二元条件逻辑 AND (&&
) 和 OR (||
)。
- 一元
!
(逻辑非)运算符。 - 二元
&
(逻辑与)、|
(逻辑或)和^
(逻辑异或)运算符。 这些运算符始终计算两个操作数。 - 二元
&&
(条件逻辑与)和||
(条件逻辑或)运算符。 这些运算符仅在必要时才计算右侧操作数。
对于整型数值类型的操作数,&
、|
和 ^
运算符执行位逻辑运算。 有关详细信息,请参阅位运算符和移位运算符。
逻辑非运算符 !
一元前缀 !
运算符计算操作数的逻辑非。 也就是说,如果操作数的计算结果为 false
,它生成 true
;如果操作数的计算结果为 true
,它生成 false
:
bool passed = false;
Console.WriteLine(!passed); // output: True
Console.WriteLine(!true); // output: False
一元后缀 !
运算符为 null 包容运算符。
逻辑“与”运算符 &
&
运算符计算操作数的逻辑与。 如果 x
和 y
的计算结果都为 true
,则 x & y
的结果为 true
。 否则,结果为 false
。
&
运算符总是计算两个操作数。 当左侧操作数的计算结果为 false
时,运算结果为 false
,而与右侧操作数的值无关。 但是,即使在这种情况下,也会计算右侧操作数。
在下面的示例中,&
运算符的右侧操作数是方法调用,无论左侧操作数的值如何,都会执行方法调用:
bool SecondOperand()
{
Console.WriteLine("Second operand is evaluated.");
return true;
}
bool a = false & SecondOperand();
Console.WriteLine(a);
// Output:
// Second operand is evaluated.
// False
bool b = true & SecondOperand();
Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True
条件逻辑 AND 运算符 &&
也计算操作数的逻辑 AND,但如果左侧操作数的计算结果为 false
,它就不会计算右侧操作数。
对于整型数值类型的操作数,&
运算符计算其操作数的位逻辑 AND。 一元 &
运算符是 address-of 运算符。
逻辑异或运算符 ^
^
运算符计算操作数的逻辑异或(亦称为“逻辑 XOR”)。 如果 x
计算结果为 true
且 y
计算结果为 false
,或者 x
计算结果为 false
且 y
计算结果为 true
,那么 x ^ y
的结果为 true
。 否则,结果为 false
。 也就是说,对于 bool
操作数,^
运算符的计算结果与不等运算符 !=
相同。
Console.WriteLine(true ^ true); // output: False
Console.WriteLine(true ^ false); // output: True
Console.WriteLine(false ^ true); // output: True
Console.WriteLine(false ^ false); // output: False
对于整型数值类型的操作数,^
运算符计算其操作数的位逻辑异或。
逻辑或运算符 |
|
运算符计算操作数的逻辑或。 如果 x
或 y
的计算结果为 true
,则 x | y
的结果为 true
。 否则,结果为 false
。
|
运算符总是计算两个操作数。 当左侧操作数的计算结果为 true
时,运算结果为 true
,而与右侧操作数的值无关。 但是,即使在这种情况下,也会计算右侧操作数。
在下面的示例中,|
运算符的右侧操作数是方法调用,无论左侧操作数的值如何,都会执行方法调用:
bool SecondOperand()
{
Console.WriteLine("Second operand is evaluated.");
return true;
}
bool a = true | SecondOperand();
Console.WriteLine(a);
// Output:
// Second operand is evaluated.
// True
bool b = false | SecondOperand();
Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True
条件逻辑 OR 运算符 ||
也计算操作数的逻辑 OR,但如果左侧操作数的计算结果为 true
,它就不会计算右侧操作数。
对于整型数值类型的操作数,|
运算符计算其操作数的位逻辑 OR。
条件逻辑“与”运算符 &&
条件逻辑与运算符 &&
(亦称为“短路”逻辑与运算符)计算操作数的逻辑与。 如果 x
和 y
的计算结果都为 true
,则 x && y
的结果为 true
。 否则,结果为 false
。 如果 x
的计算结果为 false
,则不计算 y
。
在下面的示例中,&&
运算符的右侧操作数是方法调用,如果左侧操作数的计算结果为 false
,就不执行方法调用:
bool SecondOperand()
{
Console.WriteLine("Second operand is evaluated.");
return true;
}
bool a = false && SecondOperand();
Console.WriteLine(a);
// Output:
// False
bool b = true && SecondOperand();
Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True
逻辑 AND 运算符 &
也计算操作数的逻辑 AND,但始终计算两个操作数。
条件逻辑或运算符 ||
条件逻辑或运算符 ||
(亦称为“短路”逻辑或运算符)计算操作数的逻辑或。 如果 x
或 y
的计算结果为 true
,则 x || y
的结果为 true
。 否则,结果为 false
。 如果 x
的计算结果为 true
,则不计算 y
。
在下面的示例中,||
运算符的右侧操作数是方法调用,如果左侧操作数的计算结果为 true
,就不执行方法调用:
bool SecondOperand()
{
Console.WriteLine("Second operand is evaluated.");
return true;
}
bool a = true || SecondOperand();
Console.WriteLine(a);
// Output:
// True
bool b = false || SecondOperand();
Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True
逻辑 OR 运算符 |
也计算操作数的逻辑 OR,但始终计算两个操作数。
可以为 null 的布尔逻辑运算符
对于 bool?
操作数,&
(逻辑与)和 |
(逻辑或)运算符支持三值逻辑,如下所示:
仅当其两个操作数的计算结果都为
true
时,&
运算符才生成true
。 如果x
或y
的计算结果为false
,则x & y
将生成false
(即使另一个操作数的计算结果为null
)。 否则,x & y
的结果为null
。仅当其两个操作数的计算结果都为
false
时,|
运算符才生成false
。 如果x
或y
的计算结果为true
,则x | y
将生成true
(即使另一个操作数的计算结果为null
)。 否则,x | y
的结果为null
。
下表显示了该语义:
x | y | x 和 y | x|y |
---|---|---|---|
true | true | true | true |
true | false | false | true |
true | null | null | true |
false | true | false | true |
false | false | false | false |
false | null | false | null |
null | true | null | true |
null | false | false | null |
Null | Null | Null | null |
这些运算符的行为不同于值类型可以为 null 的典型运算符行为。 通常情况下,为值类型的操作数定义的运算符也能与值类型可以为 null 的相应操作数一起使用。 如果其任一操作数的计算结果为 null
,此类运算符都会生成 null
。 不过,即使操作数之一的计算结果为 null
,&
和 |
运算符也可以生成非 null。 有关值类型可为空的运算符行为的详细信息,请参阅可为空的值类型一文的提升的运算符部分。
此外,你还可以将 !
和 ^
运算符与 bool?
操作数结合使用,如下例所示:
bool? test = null;
Display(!test); // output: null
Display(test ^ false); // output: null
Display(test ^ null); // output: null
Display(true ^ null); // output: null
void Display(bool? b) => Console.WriteLine(b is null ? "null" : b.Value.ToString());
条件逻辑运算符 &&
和 ||
不支持 bool?
操作数。
复合赋值
对于二元运算符 op
,窗体的复合赋值表达式
x op= y
等效于
x = x op y
不同的是 x
只计算一次。
&
、|
和 ^
运算符支持复合赋值,如下面的示例所示:
bool test = true;
test &= false;
Console.WriteLine(test); // output: False
test |= true;
Console.WriteLine(test); // output: True
test ^= false;
Console.WriteLine(test); // output: True
注意
条件逻辑运算符 &&
和 ||
不支持复合赋值。
运算符优先级
以下列表按优先级从高到低的顺序对逻辑运算符进行排序:
- 逻辑非运算符
!
- 逻辑与运算符
&
- 逻辑异或运算符
^
- 逻辑或运算符
|
- 条件逻辑与运算符
&&
- 条件逻辑或运算符
||
使用括号 ()
可以更改运算符优先级决定的计算顺序:
Console.WriteLine(true | true & false); // output: True
Console.WriteLine((true | true) & false); // output: False
bool Operand(string name, bool value)
{
Console.WriteLine($"Operand {name} is evaluated.");
return value;
}
var byDefaultPrecedence = Operand("A", true) || Operand("B", true) && Operand("C", false);
Console.WriteLine(byDefaultPrecedence);
// Output:
// Operand A is evaluated.
// True
var changedOrder = (Operand("A", true) || Operand("B", true)) && Operand("C", false);
Console.WriteLine(changedOrder);
// Output:
// Operand A is evaluated.
// Operand C is evaluated.
// False
要了解按优先级排序的完整 C# 运算符列表,请参阅 C# 运算符一文中的运算符优先级部分。
运算符可重载性
用户定义类型可以重载!
、&
、|
和 ^
运算符。 重载二元运算符时,对应的复合赋值运算符也会隐式重载。 用户定义类型不能显式重载复合赋值运算符。
用户定义类型无法重载条件逻辑运算符 &&
和 ||
。 不过,如果用户定义类型以某种方式重载 true 和 false 运算符以及 &
或 |
运算符,可以对相应类型的操作数执行 &&
或 ||
运算。 有关详细信息,请参阅 C# 语言规范的用户定义条件逻辑运算符部分。
C# 语言规范
有关更多信息,请参阅 C# 语言规范的以下部分: