c# - 如何清除 C# Flags Enum 中的高字节

标签 c# bit-manipulation enum-flags

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

枚举示例:

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

我当前的值(value):

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 在内的更高标志,只需不要将其添加回来即可。要清除较低的标志,返回 orig - lowerBits

在按位数学中,模 (%) 通常是您的 friend 。

附录

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

首先,请记住,这是我们正在讨论的标志,因此是位操作的一个非常具体的子集,其中模数使数学更易于阅读并且非常合适。编译器替换执行的实际数学运算将类似于以下内容,我发现读起来不太直观。

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

这确实不太难读,但到位掩码的转换是在我的原始解决方案中隐式完成的。

关于c# - 如何清除 C# Flags Enum 中的高字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43553193/

相关文章:

c# - 为计算属性实现 INotfyPropertyChanged

c# - 编译器歧义调用错误-具有Func <>或Action的匿名方法和方法组

c# - 如何在没有 BitConverter 的情况下交换 Int16 的字节顺序

c - 从 8 位到 32 位的位复制

c - C语言中如何获取内存地址并输出?

c# - 将值设置为列表 c# 中的 [Flags] 枚举

wpf - 在XAML中设置多个枚举标志

c# - 不使用 if 语句四舍五入一个数字

c# - Telerik RadControls,控制当 EnableEmbeddedScripts 为 true 时生成 ScriptResource.axd 文件的位置

c# - 如何迭代具有标志的枚举值?