这句话在C#中意味着什么?

What does this statement mean in C#?

在下面的代码块中,if ((a & b) == b)是什么意思?

1
2
3
4
5
if ((e.Modifiers & Keys.Shift) == Keys.Shift)
{
    lbl.Text +="
"
+"Shift was held down.";
}

为什么不是这样?

1
2
3
4
5
if (e.Modifiers == Keys.Shift)
{
    lbl.Text +="
"
+"Shift was held down.";
}


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

Use the FlagsAttribute custom attribute for an enumeration only if a bitwise operation (AND, OR, EXCLUSIVE OR) is to be performed on a numeric value.

Define enumeration constants in powers of two, that is, 1, 2, 4, 8, and so on. This means the individual flags in combined enumeration constants do not overlap.

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

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

只是简单的假设来解释这个概念:

1
2
3
Keys.Shift  : 001 (1)
Keys.Cancel : 010 (2)
Keys.Enter  : 100 (4)

所以:

1
e.Modifiers = Keys.Shift | Keys.Cancel | Keys.Enter equal 001 | 010 | 100 = 111

条件是:

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

它的意思是:

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

如果e.Modifiers不包含Keys.Shift

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

结果是:

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

为了使油底壳上升,这种情况检查e.Modifiers是否含有Keys.Shift


这是布尔逻辑(&;="按位与")。检查变量是否包含值。就像一个过滤器。

例:

1
2
3
a   -> 00110011
b   -> 00000011
a&b -> 00000011

在您的代码中

1
if ((e.Modifiers & Keys.Shift) == Keys.Shift)

它检查键。shift包含在e.modifiers中。


单个和号表示按位与运算符。当与具有[Flags]属性的枚举(Keys枚举具有此属性)一起使用时,它将如您所示用于确定该枚举的某个位是否已设置。

同时按下的修改键可能不止一个,所以使用它而不是直接比较。

您可以在此处阅读有关枚举标志的更多信息。向下滚动到标题为"枚举类型为位标志"的小节。您将看到一个与此非常相似的示例。


单个与号(&;)执行位与运算;双与号(&;&;)执行布尔与运算。

一个位,对两个参数的每一位执行一个和操作(因此它被称为"位智能")。因此,位和操作(或任何位操作)的输出将不是布尔值。以下是位和操作的一些示例:

1
2
1001 & 0001 = 0001
1101 & 1111 = 1101

一个布尔值,对两个布尔值进行操作,并返回一个布尔值:

1
2
true && true = true
false && true = false

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

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

由于第一个表达式(a < 3)的计算结果是false,因此结果不可能是true,因为两个表达式都必须对true进行计算才能得到true。因此,甚至不会计算第二个表达式。这被称为"短路"。但是,如果使用位和操作,则需要在执行操作之前对这两个表达式进行计算。因此,在大多数情况下,如果您只想确定两件事是否为真(布尔值),布尔值和(&;&;)将是最佳选择。

在您的示例中,代码将e.Modifiers中的单个位与Keys.Shift中的单个位进行比较。这两个参数都不代表布尔值,因此操作是按位(&;)而不是按布尔值(&;)。


第1部分

它是逻辑和运算符。

当多个标志可以在一个标志中设置时使用,例如integer:

例如,3表示二进制记数法中的00000011。例如,2表示二进制记数法中的00000010。

当您想检查A是否有标志(右边第二个位),B代表集合时,使用AND运算符:

A&B=00000010

当它等于b(或大于0)时,你就知道这个标志已经设置好了。

第2部分

equal运算符也可用于要检查"keys.shift"是否是唯一的"modifier"键,而不按其他键的情况。使用第一个代码时,也可以按其他"修改器"键,如果条件仍然为真。


&是位与运算符。它所做的是Keys是一个标志枚举,Keys中的值可以是多个值的按位组合。因此,要测试任何特定的值,您首先要测试值,然后将其与要测试的值进行比较。

例如,您可能同时按住SHIFT键和CTRL键,因此e.Modifier中的值将是Keys.ShiftKeys.Ctrl的按位组合。因此:

1
e.Modifier == Keys.Shift

是假的。按住SHIFT键,但同时按住CTRL键。如果您想知道是否按住了SHIFT,而不管其他键可能被按住,您需要首先过滤掉所有其他键。使用Keys.Shift作为过滤器可以很容易地做到这一点:

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

现在,如果按住SHIFT键,不管按下其他键是什么,都将为真,否则为假。


它使用位操作来查询是否设置了"标志"(位)(等于1)。

最好在http://msdn.microsoft.com/en-us/library/vstudio/cc138362.aspx上阅读枚举和位操作。


单和号(&;)是位AND,因此它基本上是将(a&b)的值相加,然后测试(a&b)==b中的相等性。

所以在您的示例中,它基本上是说,如果按下shift键(any key+shift)==shift。