C# &;C中具有枚举值的运算符#
我有以下代码和C# &;C中具有枚举值的运算符#,c#,enums,C#,Enums,我有以下代码和控制台。WriteLine返回Bottom,即使Bottom不在两个枚举表达式中 void Main() { Console.WriteLine(( Orientations.Left | Orientations.Bottom) & (Orientations.Right| Orientations.Top));//returns Bottom } [Flags] public enum Orientations {
控制台。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
};
问题
下面给出的代码段中返回Bottom的逻辑是什么?我对&operator的理解是,它返回公共部分,但在本例中,两个枚举表达式之间没有任何公共部分
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
1 | 2 (integer value)
01 | 10 (bitwise representation)
11 (taking the bitwise or)
Bottom
这意味着如果你写&
,这是一个按位AND,
,是一个按位OR对枚举值进行排序
因此,如果我们现在对其进行评估,我们得到:
(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
};
[标志]
公共枚举方向{
左=1,//0001
右=2,//0010
Top=4,//0100
底部=8//1000
};代码>
现在,您可以将枚举视为四个不同的标志,&
将创建交叉点,|
将创建标志的并集。在注释中,写入每个值的位表示
正如您所看到的,我们现在可以将左
、右
、顶
和底
视为独立元素,因为我们无法找到单调的按位构造(将左
、右
和顶
组合在一起构造底
(否定除外).为枚举赋值,运算符|
和&
处理枚举值,就像它们处理相应的值一样
您自己设置了枚举值的值,但没有将它们设置为正交。由于整数实际上是位字符串(具有固定长度),因此可以将其视为32维向量(每个向量元素都有域{0,1}
)。由于您将例如Bottom
定义为3
,这意味着Bottom
实际上等于Right | Top
,因为:
Right | Top
1 | 2 (integer value)
01 | 10 (bitwise representation)
11 (taking the bitwise or)
Bottom
这意味着如果你写&
,这是一个按位AND,
,是一个按位OR对枚举值进行排序
因此,如果我们现在对其进行评估,我们得到:
(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
};
[标志]
公共枚举方向{
左=1,//0001
右=2,//0010
Top=4,//0100
底部=8//1000
};
现在,您可以将枚举视为四个不同的标志,&
将创建交叉点,|
标志的并集。在注释中,将写入每个值的按位表示
正如您所看到的,我们现在可以将左
、右
、顶
和底
视为独立元素,因为我们无法找到单调的按位构造(将左
、右
和顶
组合在一起构造底
(否定除外).它是&和|位运算。在示例中:
(( 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.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,int值是Orientations.Bottom值。因此,它总是返回Orientations.Bottom。为了使标志枚举按预期工作,枚举常量必须是2的幂
在您的示例中,二进制值如下所示(为了简单起见,我只显示4位)
如果你选择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
};
请注意,每个枚举都有一个从0的隐式转换。因此,您可以执行此测试
if((myOrientations & Orientations.Vertical) != 0) {
// We have at least a Top or Bottom orientation or both
}
为了使标志枚举按预期工作,枚举常量必须是2的幂
在您的示例中,二进制值如下所示(为了简单起见,我只显示4位)
如果你选择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
};
请注意,每个枚举都有一个从0的隐式转换。因此,您可以执行此测试
if((myOrientations & Orientations.Vertical) != 0) {
// We have at least a Top or Bottom orientation or both
}
(0 | 3)和(1 | 2)
=3
。枚举只是“整型”值的语法糖。您可以在两个不同的枚举之间进行强制转换,编译器不会抱怨——即使一个枚举有另一个枚举没有的值。谢谢。根据MSDN文档,它说按位and运算符(&)将第一个操作数的每个位与第二个操作数的相应位进行比较。如果两个位都为1,则相应的结果位设置为1。否则,相应的结果位设置为0。
,它是否应仅返回0或1而不是3?这里的问题是枚举未正确设置为2的幂,因此值为ar代表