C #: получение ключа с самым низким значением в побитовом Enum - PullRequest
1 голос
/ 26 февраля 2010

У меня есть перечисление как это

[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

Ответы [ 7 ]

12 голосов
/ 26 февраля 2010

Вы можете использовать небольшую хитрость:

Key key = Key.B | Key.C;
Key lowest = (Key)((int)key & -(int)key);
6 голосов
/ 26 февраля 2010
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.

4 голосов
/ 26 февраля 2010
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);
0 голосов
/ 26 февраля 2010

Код, который вы первоначально разместили, не имеет смысла: a + b + c не имеют префикса имени типа, поэтому они не будут ссылаться на имена перечислений, на которые, по-видимому, они должны ссылаться. *

Кроме того, если вы используете побитовое И для объединения флагов, результат будет содержать все флаги в всех параметрах - в данном случае, нет.

0 голосов
/ 26 февраля 2010

Требуется быть итеративной реализацией, в которой вы проверяете биты.Я бы сделал что-то вроде этого.

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;
0 голосов
/ 26 февраля 2010
  1. Получить список всех значений в перечислении
  2. Сопоставить эти значения с неким сопоставимым типом данных
  3. Сравнить все значения и отследить самое низкое из них
  4. Преобразовать младший обратно в тип enum
0 голосов
/ 26 февраля 2010

Если у вас есть только 3 значения в перечислении, вероятно, самый быстрый и простой способ - проверить их одно за другим. Однако для общего решения вы можете попытаться преобразовать значение k1 в целое число, найти наибольшую степень 2, которая делит его, и преобразовать обратно в значение перечисления Keys.

...