Если вы сделаете перечисление [Flags]
, вы можете назначить различное битовое значение (1, 2, 4, 8, 16 ...) для каждого перечисляемого значения.Затем вы можете использовать побитовую операцию, чтобы определить, является ли значение одним из набора возможных значений.
Итак, чтобы увидеть, является ли оно C, D или F:
bool IsCDF(MyEnum enumValue)
{
return ((enumValue & (MyEnum.C | MyEnum.D | MyEnum.F)) != 0);
}
или используя HasFlag()
(менее эффективно, но более читабельно):
bool IsCDF(MyEnum enumValue)
{
return enumValue.HasFlag(MyEnum.C | MyEnum.D | MyEnum.F);
}
Обратите внимание, что это не будет работать для значения 0 (в вашем примере, 'A'), и вы должны быть осторожны, чтобы всезначения enum преобразуются в уникальные битовые значения (т. е. ненулевые степени двойки).
Преимущества этого подхода следующие:
- обычно требуется одна команда / цикл процессора длявыполнить, тогда как выполнение трех отдельных проверок «если» потребует 3 или более инструкций (в зависимости от вашей целевой платформы).
- В качестве значения перечисления можно передать набор значений, которые вы хотите проверитьцелое число) вместо необходимости использовать списки значений перечисления.
- Вы можете делать много других полезных вещей с побитовыми операциями, которые были бы неуклюжими и медленными при обычных численных / сравнительных подходах.
Полезный совет: При определении перечислений [Flags] используйте сдвиг влево (<<
), чтобы сделать значения битов более четкими (и намного сложнее ошибиться), особенно для битов более высокого порядка:
[Flags]
enum MyEnum
{
A = 1 << 0, // Equivalent to 1
B = 1 << 1, // Equivalent to 2
C = 1 << 2, // Equivalent to 4
D = 1 << 3, // Equivalent to 8
…
Big = 1 << 26, // Equivalent to 67108864
}