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.
- Get a list of all the values in the enum
- Map those values to some kind of comparable data type
- Compare all the values and keep track of the lowest one
- 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.
精彩评论