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.";
}
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.";
}
如果您查看 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
这是布尔逻辑 (& = "按位与")。使用它可以检查变量是否包含值,就像一个过滤器一样。
例如:
a -> 00110011
b -> 00000011
a&b -> 00000011
if ((e.Modifiers & Keys.Shift) == Keys.Shift)
检查Keys.Shift是否包含在e.Modifiers中。
&
是位运算符 AND,在 IT 技术中使用广泛。它的作用是,Keys
是一个标志枚举,其中的值可以是几个值的按位组合。因此,要测试任何特定的值,您首先需要将您的值与要测试的值进行 AND 运算,然后将其与要测试的值进行比较。
例如,您可能同时按下 shift 和 ctrl 键,因此 e.Modifier
中的值将是 Keys.Shift
和 Keys.Ctrl
的按位组合。所以这样做:
e.Modifier == Keys.Shift
是错误的。Shift键被按下,但Ctrl键也被按下。如果您想知道Shift键是否被按下,而不管其他键是否被按下,您需要先过滤掉所有其他键。这可以通过使用 Keys.Shift
作为过滤器轻松完成:
(e.Modifier & Keys.Shift) == Keys.Shift
一个单短线(&)执行按位与操作; 两个单短线(&&)执行布尔与操作。
按位与对每个参数的每个位执行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
中的各个位。 两个参数都不表示布尔值,因此操作是位运算(&),而不是布尔运算符(&&)。单个&符号(&)是按位与运算,它基本上是将(a & b)的值相加,然后在(a & b)== b中进行相等性测试。
因此,在您的示例中,它基本上是说如果按下Shift键(任何键+Shift)== Shift。
它使用位运算查询“标志”(位)是否设置为1。
最好阅读有关枚举和位运算的内容,请参考http://msdn.microsoft.com/en-us/library/vstudio/cc138362.aspx
第一部分
这是逻辑 AND 运算符。
当需要在一个整数中设置多个标志时,可以使用它:
例如,a 是 3,即二进制表示为 00000011。 例如,b 是 2,即二进制表示为 00000010。
当您想要检查 a 是否具有 b 表示的标志(从右边数第二位)时,使用 AND 运算符:
a & b = 00000010
当这个值等于 b(或大于 0)时,您就知道该标志已经被设置了。
第二部分
相等运算符也可用于检查是否只按下了“Keys.Shift”作为“修改键”,没有其他键被按下。当您使用第一个代码时,其他“修改键”也可能被按下,但 if 条件仍将为 true。