14

OR这可能是一个简单而简单的问题,但我仍然对决定使用bitwise 的原因有些困惑。假设我有一个A包含四个字段的类:

class A
{
    private int Field1;
    private static int Field2;
    public int Field3;
    public static int Field4;
}

并用于Reflection获取字段:

var fields = typeof (A).GetFields(BindingFlags.Public | BindingFlags.Static);

如果您是新手Reflection并且不知道如何使用BindingFlags,那么您脑海中的初始逻辑思维将是:

此行将选择所有静态 OR 公共字段,因为使用了按位 OR。以及您认为的预期结果:

Field2
Field3
Field4

但是当按下 F5 时,结果将完全不同,按位OR工作为AND

Field4

为什么不使用可能遵循逻辑思维的按位 AND 运算符。像这样:

var fields = typeof (A).GetFields(BindingFlags.Public & BindingFlags.Static);

我在MSDN中找到的话:

在某些情况下,用于组合标志的按位或运算可能被认为是一个高级概念,简单任务不需要。

请任何人都可以在这里以简单的方式解释高级概念以便理解吗?

4

3 回答 3

26

见最后一个简短的总结。

长答案:

按位或组合枚举标志的位。

例子:

  • BindingFlags.Public值为 16 或 10000(二进制)
  • BindingFlags.Static值为 8 或 1000(二进制)

按位或将这些组合如下:

10000
01000
--
11000  --> 24

按位 AND 会像这样组合它们:

10000
01000
--
00000   --> 0

这是标志的一个非常基本的概念:
每个值都是 2 的幂,例如:

  • 1 =2^0
  • 2 =2^1
  • 4 =2^2
  • 8 =2^3
  • 等等

它们的位表示始终为 a 1,其余为零:

decimal | binary
1       | 0001
2       | 0010
4       | 0100
8       | 1000

使用按位与组合它们中的任何一个总是会导致 0,因为1在同一位置没有。按位与会导致完全信息丢失。

另一方面,按位或总是会产生明确的结果。例如,当您有(二进制)1010(十进制 10)时,您知道它最初是 8 和 2。没有其他可能性可以创建 10。
正如 Default 所说,您调用的方法稍后可以使用按位 AND 运算符提取此信息:

if(10 & 8 == 8) // value 8 was set

在这种情况下,按位或基本上是将值传输到您正在调用的方法的工具。
此方法对这些值的作用与按位或的使用无关。
它可以在内部要求所​​有传递的标志与GetFields. 但它也可能只需要一个传递的标志来匹配。

对于您作为呼叫者,以下内容将是等效的:

var requiredFlags = new List<BindingFlags>();
requiredFlags.Add(BindingFlags.Public);
requiredFlags.Add(BindingFlags.Static);
typeof (A).GetFields(requiredFlags);

现在不能编译,因为GetFields不提供这样的重载,但含义与您的代码相同。

总结一下(TL; DR):

按位 AND 与布尔 AND
无关 按位 OR 与布尔 OR 无关

于 2012-09-19T08:27:32.170 回答
2

标志枚举用于表示一组布尔条件。

在您的示例中,必须满足每个布尔条件才能返回相应的字段。

标志枚举是简单的整数值,它遵循与和或运算的常用二进制规则,因此要设置几个位,您必须将表示这些位的值进行或运算。

完成此操作后,您将拥有一个设置了适当位的标志枚举。

您遇到的问题是因为您将两个不同的概念混为一谈:为标志枚举构造一组布尔条件的方式是一个概念。标志枚举的使用方式(或它所代表的)是一个不同的概念。

前者使用 OR 来构造布尔条件集。后者表示每个位都代表一个必须满足的布尔条件。

于 2012-09-19T08:29:35.327 回答
1

The implementers of GetFields() chose to interpret the combination of various ORed flags as meaning an AND combination of the selected criteria.

Which makes sense as you can always drop a criterion if you don't want the additional filter.

于 2012-09-19T08:45:15.990 回答