[英]Is there a solution for a bitwise logical AND (&) operator between two Enum values in C#
[英]& operator with enum values in C#
我有以下代码,即使两个枚举表达式中都不存在Bottom
,但Console.WriteLine
返回Bottom
。
题
在下面给出的代码片段中返回Bottom背后的逻辑是什么? 我对&运算符的理解是,它返回公共部分,但是在这种情况下,两个枚举表达式之间没有任何公共之处。
void Main()
{
Console.WriteLine(( Orientations.Left | Orientations.Bottom) &
(Orientations.Right| Orientations.Top));//returns Bottom
}
[Flags]
public enum Orientations {
Left = 0, Right= 1, Top=2, Bottom =3
};
您为枚举赋值,运算符|
和&
处理枚举值,就像它们将处理对应的值一样。
您自己设置了枚举值的值,并且没有将它们设置为正交 。 由于整数实际上是位串(具有固定长度),因此您可以将其视为32维向量(每个向量元素都具有域{0,1}
)。 由于您将实例Bottom
定义为3
,这意味着Bottom
实际上等于Right | Top
Right | Top
,因为:
Right | Top
1 | 2 (integer value)
01 | 10 (bitwise representation)
11 (taking the bitwise or)
Bottom
因此,这意味着,如果您编写&
,则这是按位AND ,而|
,是按位或在枚举值的值 。
因此,如果现在评估它,我们将得到:
(Orientations.Left|Orientations.Bottom) & (Orientations.Right|Orientations.Top)
(0 | 3 ) & (1 | 2)
3 & 3
3
Orientations.Bottom
如果要定义四个正交值 ,则需要使用两个的幂 :
[Flags]
public enum Orientations {
Left = 1, // 0001
Right = 2, // 0010
Top = 4, // 0100
Bottom = 8 // 1000
};
现在,您可以看到枚举是四个不同的标志,并且&
将创建交集,并且|
旗帜的联合。 在注释中,写入每个值的按位表示。
如您所见,我们现在可以将Left
, Right
, Top
和Bottom
视为独立元素,因为我们找不到单调的按位构造(将Left
, Right
和Top
以构造Bottom
(除法除外)。
为了使flag枚举能够按预期工作,枚举常量必须为2的幂。
在您的示例中,二进制值如下所示(为简单起见,我仅显示4位)
Left = 0 0000
Right = 1 0001
Top = 2 0010
Bottom = 3 0011
Left | Right | Top | Bottom = 0011 which is 3 or Bottom again
如果选择2的幂,则得到
Left = 1 = 2^0 0001
Right = 2 = 2^1 0010
Top = 4 = 2^2 0100
Bottom = 8 = 2^3 1000
Left | Right | Top | Bottom = 1111
即,使用2的幂时,会设置不同的位,因此它们与按位OR运算符(|)巧妙地组合在一起。
从C#7.0开始,您可以使用二进制文字
[Flags]
public enum Orientations {
Left = 0b0001,
Right = 0b0010,
Top = 0b0100,
Bottom = 0b1000
};
在以前的C#版本中,您还可以使用左移运算符获得2的幂
[Flags]
public enum Orientations {
Left = 1 << 0,
Right = 1 << 1,
Top = 1 << 2,
Bottom = 1 << 3
};
最好还包含枚举常量None = 0
因为枚举字段被初始化为default(MyEnum) == 0
,否则会导致没有对应的枚举常量的值。
您也可以像这样创建新的合并枚举值
[Flags]
public enum Orientations {
None = 0,
Left = 1 << 0,
Right = 1 << 1,
Top = 1 << 2,
Bottom = 1 << 3,
Horizontal = Left | Right,
Vertical = Top | Bottom,
All = Horizontal | Vertical
};
请注意,每个枚举都有一个从0的隐式转换。因此,您可以执行此测试
if((myOrientations & Orientations.Vertical) != 0) {
// We have at least a Top or Bottom orientation or both
}
是&和| 按位运算。 在示例中:
(( Orientations.Left | Orientations.Bottom) &
(Orientations.Right| Orientations.Top))
将替换为
((0 | 3) & (1 | 2)) with in bit (show only last 3 bit):
((000 |011) & (001 | 010))
= (011 & 011)
= 011
011的int值是3,即Orientations.Bottom值。 因此,它总是返回Orientations.Bottom。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.