逻辑布尔运算符使用 bool 操作数执行逻辑运算。 运算符包括一元逻辑非 (!)、二元逻辑 AND (&)、OR (|) 以及异或 (^),二元条件逻辑 AND (&&) 和 OR (||)。
- 一元
!(逻辑非)运算符。 - 二元
&(逻辑与)、|(逻辑或)和^(逻辑异或)运算符。 这些运算符始终计算两个操作数。 - 二元
&&(条件逻辑与)和||(条件逻辑或)运算符。 这些运算符仅在必要时才计算右侧操作数。
对于整型数值类型的操作数,&、| 和 ^ 运算符执行位逻辑运算。 有关详细信息,请参阅位运算符和移位运算符。
逻辑非运算符 !
一元前缀 ! 运算符计算操作数的逻辑非。 也就是说,如果操作数的计算结果为 true,它生成 false;如果操作数的计算结果为 false,它生成 true:
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 ^ y 计算结果为 true 且 x 计算结果为 true,或者 y 计算结果为 false 且 x 计算结果为 false,那么 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 |
|---|---|---|---|
| 是 | 是 | 是 | 是 |
| 是 | 假 | 假 | 是 |
| 是 | null | null | 是 |
| 假 | 是 | 假 | 是 |
| 假 | 假 | 假 | 假 |
| 假 | null | 假 | null |
| null | 是 | null | 是 |
| null | 假 | 假 | 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# 运算符一文中的运算符优先级部分。
运算符可重载性
用户定义类型可以重载!、&、| 和 ^ 运算符。 重载二元运算符时,对应的复合赋值运算符也会隐式重载。 从 C# 14 开始,用户定义的类型可以显式重载复合赋值运算符,以提供更高效的实现。 通常,类型重载这些运算符,因为能够在原地更新值,而无需分配新增实例来保存二元运算结果。 如果类型不提供显式重载,编译器将生成隐式重载。
用户定义类型无法重载条件逻辑运算符 && 和 ||。 不过,如果用户定义类型以某种方式重载 true 和 false 运算符以及 & 或 | 运算符,可以对相应类型的操作数执行 && 或 || 运算。 有关详细信息,请参阅 C# 语言规范的用户定义条件逻辑运算符部分。
C# 语言规范
有关更多信息,请参阅 C# 语言规范的以下部分: