На днях столкнулся с необходимостью задания битовой маски
для пользовательского перечисления. Вспомнил, что когда то очень
быстро понял роль задания маски на простом примере. И сейчас я хочу поделиться своим опытом.
Многие знакомы с перечислениями:
enum Season
{
Winter,
Spring,
Summer,
Autumn
}
Здесь мы описали перечисление времен года. Их всего четыре.
А если мы хотим добавить межсезонье?! Тогда следует еще добавить столько же значений.
А если мы хотим получить все месяцы года, то мы определяем перечисление с 12-ю прозициями.
Конечно, следует позаботиться о том, что б ни одно значение в перечислении не имело дубликат среди остальных.
То-есть, каждое значение в перечисление должно быть уникальным. Собственно, для этого перечисления и существуют.
Так все таки при чем тут битовая маска.
Вспомним битовое представление данных 20, 21, 22, 23, …, 2n.
Этот ряд и есть последовательность чисел 1,2,4,8,…,1024.
Кто мало знаком с компьютерными вычислениями скажу, что в электронных представлениях битовая запись записывается в
обратном направлении, то-есть 1024, …, 8, 4, 2, 1. Переведя на язык битовых флагов мы получим битовое
представление любого числа, где знак «1» соответствует присутствию значения в данной позиции,
«0» - позиция не несет нагрузки.
К примеру, число 1 представлено записью 00000001 (количество предшествующих нулей не имеет значения).
То-есть имеем 0+0+0+0+0+0++0+20. Число 2 представляется записью 000010 – это соответствует 0+0+0+0+21+0.
Число 3 – 000011 – 0+0+0+0+21+20.
Число 13 представляем 0001101 -> 0+0+0+23+22+0+20 (0+0+0+8+4+0+1).
Смысл битового представления, я думаю ясен. Главное премущество битового представления – это,
во первых, отсутствие дублирующихся значений, а во вторых, гарантия того, что любое число может быть
получено строго одним набором битовых позиций. Не существует два разных набора бит, сумма значений
которых даст одинаковый результат. Можете это сами проверить – любое число будет иметь строго единственную
последовательность нулей и единиц.
Вернемся к нашему вопросу. Что если мы создаем перечисление, представляющее значения из битовой линейки.
Ну к примеру:
[Flags]
enum MyBit
{
V1 = 1,
V2 = 2,
V3 = 4,
V4 = 8,
V5 = 16
}
Теперь попробуем вывести битовые комбинации для чисел от 1 до 31
class Program
{
[Flags]
enum MyBit
{
V1 = 1,
V2 = 2,
V3 = 4,
V4 = 8,
V5 = 16
}
static void Main(string[] args)
{
ShowAllBits();
Console.ReadKey();
}
static void ShowAllBits()
{
for (int i = 1; i < 32; i++)
Console.WriteLine("{0} - {1}", i, (MyBit)i);
}
}
Результаты работы программы:

Как видим, любое число из диапазона [1, 31] представлено сугубо одним битовым набором. Заметьте, что следующим значением в перечислении может идти только V6 = 32.
В этом и состоит значение атрибута Flags.