我有这样的枚举

[Flags]
public enum Key
{
  None = 0,
  A = 1,
  B = 2,
  C = 4
}

我有以下内容

Key k1 = Key.A | Key.B | Key.C;

我想获取 k1 中具有最低值的密钥。我怎样才能做到这一点?

例子:

Key k1 = Key.A | Key.B | Key.C; // I want a 
Key k2 = Key.B | Key.C; // I want b
Key k3 = Key.A | Key.C; // I want a
有帮助吗?

解决方案

Keys key = Keys.b | Keys.c;

var lowest = Enum.GetValues(typeof(Keys))
    .Cast<Keys>()
    .OrderBy(x => x)
    .FirstOrDefault(x => key.HasFlag(x));

略更有效和.NET 4.0肥胖型版本的LINQ方法。

其他提示

可以使用位招:

Key key = Key.B | Key.C;
Key lowest = (Key)((int)key & -(int)key);
Keys key = Keys.b | Keys.c;

var lowest = Enum.GetValues(typeof(Keys))
    .OfType<Keys>()
    .Where(x => (x & key) != 0)
    .OrderBy(x => x)
    .DefaultIfEmpty((Keys)0);

Console.WriteLine(lowest);

如果您在枚举只有3个值可能是最快和最简单的是检查他们一个接一个。对于一般的解决方案,但是,你可能想尝试将该值转换k1到整数,找到2划分它的最大功率和转换回键枚举值。

  1. 获取枚举中所有值的列表
  2. 将这些值映射到某种 可比较的数据类型
  3. 比较所有值并保留 最低的轨道
  4. 将最低的转换回 枚举类型

需要是其中在测试位的迭代实现。我会做这样的事情。

unsigned int k = (unsigned int) k1;
int pos = -1;
while (k) {
   pos++;
   if (k & 0x1) break;
   k >>= 1;
}
Keys lowestKey = 0;
if (pos >= 0) lowestKey = 0x1 << pos;

您最初发布没有意义的代码:A + B + C不是一个类型,名称前缀,所以他们不会参考他们似乎意在指枚举名称

此外,如果您使用的是按位和TO标志相结合,结果将包含在所有标志的所有的paramters - 在这种情况下,没有

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top