无法解释此 BitVector32 的状态

Cannot interpret state of this BitVector32

我现在正在调试一些代码(VS 2019,.NET Framework 4.7.2),在断点处停止,使用 立即 Window 来评估变量.我有一个 BitVector32,我不了解它的状态。这是IW的内容:

stillInHand.ToString()
"BitVector32{00000000000000000000000000001100}"
stillInHand
{BitVector32{00000000000000000000000000001100}}
    Data: 12
stillInHand[0]
true
stillInHand[1]
false
stillInHand[2]
false
stillInHand[3]
false
stillInHand[4]
true
stillInHand[5]
false
stillInHand[6]
false
stillInHand[7]
false

没有调用任何 Create* 方法,并且 stillInHand 是使用 BitVector32(Int32) 构造函数创建的。索引 2 和 3 不应该是 true 而其他的都是 false 吗?

其实,这个问题关系到对BitVector32[ ]的索引的理解。

首先stillInHand[1]并不是要得到stillInHand(BitVector32)的第二位。它表示这个动作:使用00 00 … 00 01与stillInHand(BitVector32).

进行&(AND)运算

举个例子stillInHand(BitVector32)00 00 00 00 00 … 00 00 00 11 00100 00 00 00 00 … 00 00 00 00 01。然后进行&(AND)运算。

00 00 00 00 00 … 00 00 00 11 00        12      &(AND)

00 00 00 00 00 … 00 00 00 00 01       `1`

--------------------------------------------

00 00 00 00 00 … 00 00 00 00 00

并且可以看到最后一位(关注索引值1)由1变为0,所以结果会是false,如果您输出或看到 stillInHand[1].

的结果

所以,对于stillInHand[2],可以看到

00 00 00 00 00 … 00 00 00 11 00        12      &(AND)

00 00 00 00 00 … 00 00 00 00 10        2

--------------------------------------------

00 00 00 00 00 … 00 00 00 00 00

倒数第二位(关注索引值2)由1变为0,所以结果也会是false

而对于stillInHand[8],你可以看到

00 00 00 00 00 … 00 00 00 11 00        12      &(AND)

00 00 00 00 00 … 00 00 00 10 00        8

--------------------------------------------

00 00 00 00 00 … 00 00 00 10 00

倒数第四位(关注索引值8)没有变化,仍然是1,所以结果会是true.

实际上,如果你从这里分析源代码:Reference Source,你可以看到这些代码:

/// <devdoc>
///    <para>Gets or sets a value indicating whether all the specified bits are set.</para>
/// </devdoc>

public bool this[int bit] {
   get {
            return (data & bit) == (uint)bit; 
            //clear other bits (to 0) through the AND operation of the data and mask.
            //If the result of the operation is equal to the mask, return true.
            //Otherwisse, return false.
       }
   set {
            if (value) {
                data |= (uint)bit;
                //data = data OR mask, set the specified bit to “1”
            }
            else {
                data &= ~(uint)bit;
                //data = data AND ~mask, set the specified bit to “0”
            }
        }
}
 

当然,你可以把it当成mask,这样就很容易理解了。