布尔逻辑运算符(C# 参考)

以下运算符使用 bool 操作数执行逻辑运算:

对于整型数值类型的操作数,&|^ 运算符执行位逻辑运算。 有关详细信息,请参阅位运算符和移位运算符

逻辑非运算符 !

一元前缀 ! 运算符计算操作数的逻辑非。 也就是说,如果操作数的计算结果为 false,它生成 true;如果操作数的计算结果为 true,它生成 false

bool passed = false;
Console.WriteLine(!passed);  // output: True
Console.WriteLine(!true);    // output: False

从 C# 8.0 起,一元后缀 ! 运算符为 null 包容运算符

逻辑与运算符 &

& 运算符计算操作数的逻辑与。 如果 xy 的计算结果都为 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 计算结果为 truey 计算结果为 false,或者 x 计算结果为 falsey 计算结果为 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

对于整型数值类型的操作数,^ 运算符计算其操作数的位逻辑异或

逻辑或运算符 |

| 运算符计算操作数的逻辑或。 如果 xy 的计算结果为 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

条件逻辑与运算符 &&

条件逻辑与运算符 &&(亦称为“短路”逻辑与运算符)计算操作数的逻辑与。 如果 xy 的计算结果都为 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

逻辑与运算符& 也计算操作数的逻辑与,但始终计算两个操作数。

条件逻辑或运算符 ||

条件逻辑或运算符 ||(亦称为“短路”逻辑或运算符)计算操作数的逻辑或。 如果 xy 的计算结果为 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

逻辑或运算符| 也计算操作数的逻辑或,但始终计算两个操作数。

可以为 null 的布尔逻辑运算符

对于 bool? 操作数,&(逻辑与)|(逻辑或)运算符支持三值逻辑,如下所示:

  • 仅当其两个操作数的计算结果都为 true 时,& 运算符才生成 true。 如果 xy 的计算结果为 false,则 x & y 将生成 false(即使另一个操作数的计算结果为 null)。 否则,x & y 的结果为 null

  • 仅当其两个操作数的计算结果都为 false 时,| 运算符才生成 false。 如果 xy 的计算结果为 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# 语言规范的以下部分:

请参阅