我有以下代码,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
};
发布于 2017-12-02 01:52:03
为了让标志枚举按预期工作,枚举常量必须是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
}
发布于 2017-12-02 01:44:15
它是& and |位运算。在示例中:
(( 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。
https://stackoverflow.com/questions/47598513
复制相似问题