【问题标题】:Check if a bitmask consists of multiple flags [duplicate]检查位掩码是否由多个标志组成[重复]
【发布时间】:2017-04-23 13:56:00
【问题描述】:

注意,这不是这个问题的欺骗:

Testing if a bitmask has one and only one flag

我需要验证位掩码是否包含多个标志。我想出了这种方法,但由于枚举和强制转换,我不太喜欢它。

[Flags]
enum MyFlags { a = 1, b = 2, c = 4, d = 8 }

var flags = Enum.GetValues(typeof(MyFlags)).Cast<MyFlags>();

Console.WriteLine(flags.Any(f => f == (MyFlags.a | MyFlags.c))); //false
Console.WriteLine(flags.Any(f => f == MyFlags.b)); //true

【问题讨论】:

  • 如果您明确了所测试的输入/值是什么,您的示例可能会更清楚。我假设这是您目前获得文字表达式的地方,但它可能是已经设置的MyFlags 参数/变量?此外,如果您正在使用具有命名组合的枚举(例如FileShare.ReadWrite,不完全确定您的期望
  • 如果字面上只是“这个值有多个位集”,那么您正在寻找的似乎是population count

标签: .net bitwise-operators


【解决方案1】:

如果你想要测试一个位掩码是否包含标志,你可以这样做

MyFlags flag = MyFlags.b | MyFlags.d | MyFlags.a;

Console.WriteLine(flag.HasFlag(MyFlags.b));             // true
Console.WriteLine(flag.HasFlag(MyFlags.a | MyFlags.b)); // true
Console.WriteLine(flag.HasFlag(MyFlags.c | MyFlags.b)); // false

编辑
你也可以看看BitArray
https://msdn.microsoft.com/en-us/library/system.collections.bitarray(v=vs.110).aspx

基本上你只需要计算BitArray中设置为1的位数

您可以使用这种快速的 GetCardinality 方法来计算它们(或者,您也可以使用 for 循环来完成):Counting bits set in a .Net BitArray Class。那么:

public static bool HasExactlyOneBitSet(Enum e)
{
    return GetCardinality(new BitArray(new[] { (int)(object)e })) == 1;
}

你会这样使用它:

HasExactlyOneBitSet(MyFlags.A);             // true
HasExactlyOneBitSet(MyFlags.A | MyFlags.C); // false

【讨论】:

  • 这不是我想做的。这将检查位掩码是否包含特定的设置标志。我想确保传入的位掩码由可用标志集中的单个标志组成。我也不知道枚举类型,所以它必须像我的 OP 示例中那样是动态的。最后,HasFlags 是邪恶的,你不应该使用它。
  • 好吧,我刚刚编辑了我的答案...
猜你喜欢
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 2019-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
  • 2014-09-25
相关资源
最近更新 更多