如何清除C#标志中的更高字节



我正在使用标志枚举来跟踪每个数据记录数据迁移过程的完成阶段。我需要一种将重置回到指定阶段的方法,在那里我可以开始重新处理数据记录的迁移。如何将较高的字节重置在标志中枚举?

示例枚举:

[Flags]
public Enum MigrationStages {
  None = 0,
  Started = 1,
  MiddleStage = 2,
  WrappingUp = 4,
  Finished = 8
}

我的当前价值:

var currentStage = 
    MigrationStages.None 
    | MigrationStages.Started 
    | MigrationStages.MiddleStage
    | MigrationStages.WrappingUp
    | MigrationStages.Finished;

我想重置回MigrationStages.MiddleStage,以使重新处理从那里开始。

位数学不再使用。因此,当我去寻找答案时,我没有发现任何帮助,所以我解决了。与世界分享我的数学,以防其他人觉得有用。

我创建了一个简单的助手方法来执行此操作,如下所示:

public static MigrationStage ClearHigherFlags(MigrationStage orig, MigrationStage highBit)
{
    var lowerBits = (int)orig % (int)highBit;
    return highBit + lowerBits;
}

用法示例:

currentStage = ClearHigherFlags(currentStage, MigrationStages.MiddleStage);

显然,如果要清除包括highBit在内的更高标志,请不要添加它。要清除较低的标志,return orig - lowerBits

在位数学中,模量(%(通常是您的朋友。

附录

有些人会找到这个答案,并认为这并不是真正的数学。我希望这能帮助那些人。

首先,请回想一下,这是我们正在谈论的标志,因此,一个非常具体的位操作子集,其中模量使数学更易于阅读并且非常合适。编译器更换执行的实际数学将是以下内容,我发现阅读的直观得多。

public static MigrationStage ClearHigherFlags(MigrationStage orig, MigrationStage highBit)
{
    var bitMask = highBit - 1;
    var lowerBits = orig & bitMask;
    return highBit + lowerBits;
}

确实不太难阅读,但是在我的原始解决方案中隐含地进行了蒙版。

如果要使用位操作,可以这样做:

var lowbits = MigrationStages.MiddleStage | MigrationStages.Started;

然后清除示例中的高点:

currentStage = currentStage & lowbits;

也许这会更有意义:

               8  4  2  1
               ==========
lowbits        0  0  1  1
currentvalue   1  1  1  1
               ==========
AND (&)        0  0  1  1

清除两个高位

最新更新