开发者

C#: Getting lowest valued key in a bitwise Enum

开发者 https://www.devze.com 2022-12-21 04:34 出处:网络
I h开发者_开发知识库ave enum like this [Flags] public enum Key { None = 0, A = 1, B = 2, C = 4 } I have the following

I h开发者_开发知识库ave enum like this

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

I have the following

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

I want to get the key in k1 that has the lowest value. How can I do that?

Example:

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


You can use a bit trick:

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))
    .Cast<Keys>()
    .OrderBy(x => x)
    .FirstOrDefault(x => key.HasFlag(x));

Slightly more efficient and .NET 4.0-ish version of the LINQ method.


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);


If you have only 3 values in the enum probably the fastest and easiest is to check them one by one. For a general solution, however, you might want to try to convert the value of k1 to integer, find the largest power of 2 that divides it and convert it back to Keys enum value.


  1. Get a list of all the values in the enum
  2. Map those values to some kind of comparable data type
  3. Compare all the values and keep track of the lowest one
  4. Convert the lowest one back to the enum type


Needs to be an iterative implementation where you test bits. I would do something like this.

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;


The code you originally posted doesn't make sense: a+b+c aren't prefixed by a type-name, so they won't refer to the enum names they seem to be intended to refer to.

Also, if you use a bitwise AND to combine flags, the result will contain all flags on in all paramters - in this case, none.

0

精彩评论

暂无评论...
验证码 换一张
取 消