为什么有人在枚举声明中使用<<运算符?

JSB*_*ach 39 c# enums operators

我正在查看我目前在项目中的代码并找到类似这样的代码:

public enum MyEnum
{
    open     = 1 << 00,
    close    = 1 << 01,
    Maybe    = 1 << 02,
    ........
}
Run Code Online (Sandbox Code Playgroud)

<<操作数是移位操作数,通过移动在所述第二操作数指定的数量的比特离开第一操作数.

但是为什么有人会在enum声明中使用它呢?

Mar*_*ius 40

这允许你做这样的事情:

var myEnumValue = MyEnum.open | MyEnum.close;
Run Code Online (Sandbox Code Playgroud)

无需计算2的倍数的位值.

(像这样):

public enum MyEnum
{
    open     = 1,
    close    = 2,
    Maybe    = 4,
    ........
}
Run Code Online (Sandbox Code Playgroud)

  • 什么替代解决方案将提供超过64个正交状态? (2认同)
  • @GrijeshChauhan大多数平台?这是C#所以整数类型的大小不依赖于平台.`<<`运算符的左操作数的类型决定了要使用的重载.例如,使用`s`为整数,`1 << s`给出32位`int`,`1u << s`给出32位无符号`uint`,`1L << s`给出64位`long`,`1ul << s`是`ulong`,`(BigInteger)1 << s`或`BigInteger.One << s`给出一个任意大小的整数(需要引用`System.Numerics.dll `组装). (2认同)
  • @GrijeshChauhan在C#中,你可以像这样制作一个8位枚举类型:`public enum Color:byte {Red,Yellow,Green,Blue,}` (2认同)

Lee*_*Lee 22

这通常与位域一起使用,因为它清楚模式是什么,无需手动计算正确的值,从而减少出错的机会

[Flags]
public enum SomeBitField
{
    open = 1 << 0    //1
    closed = 1 << 1  //2
    maybe = 1 << 2   //4
    other = 1 << 3   //8
    ...
}
Run Code Online (Sandbox Code Playgroud)


Ric*_*ing 10

避免Flags手动输入枚举值.

public enum MyEnum
{
    open     = 0x01,
    close    = 0x02,
    Maybe    = 0x04,
    ........
}
Run Code Online (Sandbox Code Playgroud)

  • +1.人们可能会在这样的"枚举"中使用"[Flags]"来澄清用法......但不是每个人都在关心. (5认同)

McG*_*gle 6

它只是意味着更清晰/更直观的写位方式.1,2,3是比0x1,0x2,0x4等更易读的序列.


It'*_*ie. 6

这是为了使你可以结合的枚举.

这有效意味着:

public enum MyEnum
{
    open = 1;
    close = 2;
    Maybe = 4;
    //...
}
Run Code Online (Sandbox Code Playgroud)

这只是创建[Flags]枚举的一种更加防弹的方法.


ind*_*div 6

这里有很多答案描述了这个机制允许你做什么,但不是你想要使用它的原因.这就是原因.

精简版:

这种表示法有助于与其他组件交互并与其他工程师通信,因为它明确告诉您正在设置或清除单词中的哪个位而不是在数值中隐藏该信息.

所以我可以打电话给你,然后说"嘿,打开文件有什么用?" 而且你会说,"比特0".我会在我的代码中写open = 1 << 0.因为右边的数字<<告诉你位数.

.

长版:

传统上,字中的位从右到左编号,从零开始.因此,最低有效位是0位,当你走向最重要的位时,你会计数.以这种方式标记位有几个好处.

一个好处是,无论字大小,您都可以谈论相同的位.例如,我可以说在32位字0x384A和8位字0x63中都设置了位6和1.如果你在另一个方向编号你的位,你就不能这样做.

另一个好处是位的值只是2位上升到位位置的功率.例如,二进制0101具有第2位和第0位设置.位2为4 (2^2)数字提供值,位0提供值1(2 ^ 0).所以数字的值当然是4 + 1 = 5.

那个冗长的背景解释让我们明白了这一点:<<符号通过查看它来告诉你位数.

语句中的数字1本身1 << n只是在位位置0中设置的单个位.当您向左移动该数字时,您将该位设置位移动到数字中的其他位置.方便的是,您移动的金额会告诉您将要设置的位数.

1 << 5:   This means bit 5.   The value is 0x20.
1 << 12:  This means bit 12.  The value is 0x40000.
1 << 17:  This means bit 17.  The value is 0x1000000.
1 << 54:  This means bit 54.  The value is 0x40000000000000.
          (You can probably see that this notation might be helpful if
          you're defining bits in a 64-bit number)
Run Code Online (Sandbox Code Playgroud)

当您与另一个组件交互时,这种表示法真的很方便,比如将一个字中的位映射到硬件寄存器.就像你可能有一个设备在你写第7位时打开.所以硬件工程师会写一个数据表,说第7位启用设备.你会写下你的代码ENABLE = 1 << 7.很简单.

哦拍.工程师刚刚给数据表发了一个勘误,说应该是第15位,而不是第7位.没关系,只需将代码更改为 ENABLE = 1 << 15.

如果ENABLE同时设置了第7位和第1位,该怎么办?

ENABLE = (1 << 7) | (1 << 1).

起初它可能看起来很奇怪和迟钝,但你会习惯它.如果你明确需要知道某些东西的位数,你会很感激.