1

在所有按位示例中,我看到值呈指数增长(1、2、4、8 等)。但是,在下面的枚举中,我使用 1、2、3、4(如果你愿意,请原谅 VB):

<Flags()>
Enum BitWiseTest
    One = 1
    Two = 2
    Three = 3
    Four = 4
End Enum

令我惊讶的是,以下代码有效:

Dim TestBits As BitWiseTest

TestBits = TestBits Or BitWiseTest.One
TestBits = TestBits Or BitWiseTest.Two
TestBits = TestBits Or BitWiseTest.Three
TestBits = TestBits Or BitWiseTest.Four

Dim BitToRemove As BitWiseTest

BitToRemove = BitWiseTest.Two

TestBits = Not BitToRemove

Console.WriteLine(TestBits And BitToRemove)

注释掉该行将TestBits = Not BitToRemove告诉您不删除该位将告诉您它仍然存在。更改BitToRemove = BitWiseTest.Two为使用另一个枚举值将表明它也适用于其他位。

它似乎完美无缺,那么我在各处看到的关于按位的值的指数递增是怎么回事?

4

3 回答 3

3

它似乎完美无缺

这取决于您所说的“完美无缺”。

真的想要BitWiseTest.OneBitwiseTest.Two等于BitwiseTest.Three吗?这就是你现在会得到的,这通常不是理想的......通常你希望标志是独立的,这意味着它们需要由二进制表示中的独立位表示 - 而这正是你得到的通过使用 1、2、4、8、16 等值。

于 2013-02-21T14:56:11.333 回答
2

通常有两种枚举。对于枚举:

  1. 使用其中一个值。
  2. 使用值的组合。

使用其中一个值

在这种情况下,您可以随意编号枚举成员。如果它们的含义相同,您甚至可以拥有两个具有相同值的成员。例如:

Enum Comparison
    None = 0
    CaseSensitive = 1
    IgnoreCase = 2

    Default = 1
End Enum

使用了值的组合

一个值现在是布尔值:它可以是on(已使用、指定)或off(未使用或未指定)。这很好地转换为位,即 1(开)或 0(关)。为了能够将这些值彼此区分开来,您应该使用 2 的幂。然后,对于任何特定位,只有一个值可以将该位设置为开或关。

<Flags()>
Enum NumberStyles
    None = 0                    ' Binary:          0
    AllowLeadingWhite = 1       ' Binary:          1
    AllowTrailingWhite = 2      ' Binary:         10
    AllowLeadingSign = 4        ' Binary:        100
    AllowTrailingSign = 8       ' Binary:       1000
    AllowParentheses = 16       ' Binary:      10000
    AllowDecimalPoint = 32      ' Binary:     100000
    AllowThousands = 64         ' Binary:    1000000
    AllowExponent = 128         ' Binary:   10000000
    AllowCurrencySymbol = 256   ' Binary:  100000000
    AllowHexSpecifier = 512     ' Binary: 1000000000
End Enum

现在您可以组合两个值来获得一个新值,并且可以区分这些值:

Dim testBits As NumberStyles
testBits = NumberStyles.AllowHexSpecifier _
        Or NumberStyles.AllowTrailingWhite _
        Or NumberStyles.AllowLeadingWhite       ' Binary: 1000000011

' If (1000000011 And 1000000000) <> 0 Then
If testBits.HasFlag(NumberStyles.AllowHexSpecifier) Then
    ' Do something
End If

如果有意义的话,您也可以将这些组合添加到枚举中:

<Flags()>
Enum NumberStyles
    ' ...
    Integer = 7                 ' Binary:        111
    Number = 111                ' Binary:    1101111
    Float = 167                 ' Binary:   10100111
    Currency = 383              ' Binary:  101111111
    HexNumber = 515             ' Binary: 1000000011
End Enum

关于你的例子

查看示例的二进制值。值One和是TwoFour的幂,但Three不是。如果我扩展您的示例,也许您会看到问题:

<Flags()>
Enum BitWiseTest
    One = 1     ' Binary:    1
    Two = 2     ' Binary:   10
    Three = 3   ' Binary:   11
    Four = 4    ' Binary:  100
    Five = 5    ' Binary:  101
    Six = 6     ' Binary:  110
    Seven = 7   ' Binary:  111
End Enum

现在,做Six Or Three = Seven,这通常不是你想要的。也是when value And Twois ,or ,这也可能是你现在想要的。原因是在 中设置的一位也存在于 中,这取决于您选择值的方式。TruevalueThreeSixSevenTwoThreeSixSeven

于 2013-02-21T19:16:08.013 回答
0

它们不必是指数级的,没有语言限制。

在大多数情况下,将它们定义为指数是有意义的,因此它们彼此独立。在少数情况下,您可能会受益于将指数标志值与预定义的状态值相结合:

public enum KitchenState{
    NothingHappening = 0,

    PanOnStove = 1,
    StoveOn = 2,
    Preheating = 3,

    EggsInPan = 4,
    EggsCooking = 7, 
}

在这种情况下,预热和 EggsCooking 是状态,PanOnStove、StoveOn 和 EggsInPan 是标志。这主要是一个噱头,但有时会派上用场

于 2013-02-21T15:20:32.140 回答