我正在使用标志枚举来跟踪每个数据记录数据迁移过程的完成阶段。我需要一种将重置回到指定阶段的方法,在那里我可以开始重新处理数据记录的迁移。如何将较高的字节重置在标志中枚举?
示例枚举:
[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
清除两个高位