这个语句在C#中是什么意思?

11

if ((a & b) == b)在以下代码块中的含义是什么?

if ((e.Modifiers & Keys.Shift) == Keys.Shift)
{
    lbl.Text += "\n" + "Shift was held down.";
}

为什么不是这样呢?

if (e.Modifiers == Keys.Shift)
{
    lbl.Text += "\n" + "Shift was held down.";
}

4
按位与和位标志,请先谷歌搜索这两个术语。 - mbeckish
可能是What does a single | or & mean?的重复问题。 - Conrad Frix
8个回答

17

如果您查看 Keys 枚举,这是带有 [FlagsAttribute] 属性的标志枚举。

仅在对数字值执行按位操作 (AND、OR、EXCLUSIVE OR) 时才为枚举使用 FlagsAttribute 自定义属性。

将枚举常量定义为二的幂,即 1、2、4、8 等。这意味着组合枚举常量中的各个标志不重叠。

因此,e.Modifiers 可能是多个枚举的组合:

e.Modifiers = Keys.Shift | Keys.Cancel | Keys.Enter

只需非常简单的假设来解释这个概念:

Keys.Shift  : 001 (1)
Keys.Cancel : 010 (2)
Keys.Enter  : 100 (4)
所以:
e.Modifiers = Keys.Shift | Keys.Cancel | Keys.Enter equal 001 | 010 | 100 = 111

并且条件:

    e.Modifiers & Keys.Shift equal 111 & 001 = 001

它的意思是:

 e.Modifiers & Keys.Shift == Keys.Shift

如果 e.Modifiers 不包含 Keys.Shift:

e.Modifiers = Keys.Cancel | Keys.Enter (110)

所以结果将会是:

e.Modifiers & Keys.Shift equals 110 & 001 = 000 (is not Keys.Shift)

总之,此条件检查e.Modifiers是否包含Keys.Shift


5

这是布尔逻辑 (& = "按位与")。使用它可以检查变量是否包含值,就像一个过滤器一样。

例如:

a   -> 00110011
b   -> 00000011
a&b -> 00000011

在你的代码中
if ((e.Modifiers & Keys.Shift) == Keys.Shift)

检查Keys.Shift是否包含在e.Modifiers中。


4
一个单独的&符号指的是位运算中的按位与操作符。当与具有[Flags]属性的枚举一起使用时,例如Keys枚举,它被用来确定该枚举的某个位是否设置或未设置,就像你展示的那样。
由于可能同时按下多个修饰键,因此使用它而不是直接比较。
您可以在这里阅读有关枚举标志的更多信息。滚动到标题为“枚举类型作为位标志”的子部分。您将看到一个非常类似于此的示例。

3

& 是位运算符 AND,在 IT 技术中使用广泛。它的作用是,Keys 是一个标志枚举,其中的值可以是几个值的按位组合。因此,要测试任何特定的值,您首先需要将您的值与要测试的值进行 AND 运算,然后将其与要测试的值进行比较。

例如,您可能同时按下 shift 和 ctrl 键,因此 e.Modifier 中的值将是 Keys.ShiftKeys.Ctrl 的按位组合。所以这样做:

e.Modifier == Keys.Shift

是错误的。Shift键被按下,但Ctrl键也被按下。如果您想知道Shift键是否被按下,而不管其他键是否被按下,您需要先过滤掉所有其他键。这可以通过使用 Keys.Shift 作为过滤器轻松完成:

(e.Modifier & Keys.Shift) == Keys.Shift

如果按住Shift键,无论其他键是否同时按下,此时该条件将为真;否则为假。

3

一个单短线(&)执行按位与操作; 两个单短线(&&)执行布尔与操作。

按位与对每个参数的每个位执行AND操作(因此称为“按位”)。 因此,按位AND操作(或任何按位操作)的输出不会是布尔值。以下是一些按位AND操作的示例:

1001 & 0001 = 0001
1101 & 1111 = 1101

布尔与运算是针对两个布尔值进行操作并返回一个布尔值:

true && true = true
false && true = false

短路计算
布尔值AND操作(&&)也可以在返回布尔值的两个表达式上执行:

int a = 5;
int b = 10;
bool result = (a < 3) && (b > 3);
// result will be false;

由于第一个表达式 (a < 3) 的值为 false,结果不可能是 true,因为要使结果为 true,两个表达式都必须求值为 true。因此,第二个表达式甚至不会被求值。这被称为“短路”。然而,在位与操作中,必须在执行操作之前评估两个表达式。因此,在大多数情况下,当您只想确定两个事物是否为真(布尔值)时,布尔 AND(&&)将是最佳选择。
在您的示例中,代码正在比较e.Modifiers中的各个位与Keys.Shift中的各个位。 两个参数都不表示布尔值,因此操作是位运算(&),而不是布尔运算符(&&)。

3

单个&符号(&)是按位与运算,它基本上是将(a & b)的值相加,然后在(a & b)== b中进行相等性测试。

因此,在您的示例中,它基本上是说如果按下Shift键(任何键+Shift)== Shift。


2
它们并没有相加!应用按位与运算符和加法之间存在着巨大的区别。 - antonijn
是的,我明白了。我只是想以简单的方式解释一下。抱歉冒犯了。 - Bryan Hobbs

3

3

第一部分

这是逻辑 AND 运算符。

当需要在一个整数中设置多个标志时,可以使用它:

例如,a 是 3,即二进制表示为 00000011。 例如,b 是 2,即二进制表示为 00000010。

当您想要检查 a 是否具有 b 表示的标志(从右边数第二位)时,使用 AND 运算符:

a & b = 00000010

当这个值等于 b(或大于 0)时,您就知道该标志已经被设置了。

第二部分

相等运算符也可用于检查是否只按下了“Keys.Shift”作为“修改键”,没有其他键被按下。当您使用第一个代码时,其他“修改键”也可能被按下,但 if 条件仍将为 true。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接