#enums
#перечисления
Вопрос:
Недавно я видел объявление enum, которое выглядит следующим образом:
<Serializable()>
<Flags()>
Public Enum SiteRoles
ADMIN = 10 << 0
REGULAR = 5 << 1
GUEST = 1 << 2
End Enum
Мне было интересно, может ли кто-нибудь объяснить, что делает синтаксис «<<» или для чего он используется? Спасибо…
Ответ №1:
Перечисление имеет атрибут Flags, который означает, что значения используются в качестве битовых флагов.
Битовые флаги полезны при представлении более одного атрибута в переменной
Это флаги для 16-разрядной (атрибутивной) переменной (надеюсь, вы видите шаблон, который может продолжаться до X количества бит., ограниченный, конечно, типом платформы / переменной)
BIT1 = 0x1 (1 << 0)
BIT2 = 0x2 (1 << 1)
BIT3 = 0x4 (1 << 2)
BIT4 = 0x8 (1 << 3)
BIT5 = 0x10 (1 << 4)
BIT6 = 0x20 (1 << 5)
BIT7 = 0x40 (1 << 6)
BIT8 = 0x80 (1 << 7)
BIT9 = 0x100 (1 << 8)
BIT10 = 0x200 (1 << 9)
BIT11 = 0x400 (1 << 10)
BIT12 = 0x800 (1 << 11)
BIT13 = 0x1000 (1 << 12)
BIT14 = 0x2000 (1 << 13)
BIT15 = 0x4000 (1 << 14)
BIT16 = 0x8000 (1 << 15)
Чтобы установить бит (атрибут), вы просто используете побитовый оператор or:
UInt16 flags;
flags |= BIT1; // set bit (Attribute) 1
flags |= BIT13; // set bit (Attribute) 13
Чтобы определить, какой бит (атрибут) установлен, вы просто используете побитовый оператор and:
bool bit1 = (flags amp; BIT1) > 0; // true;
bool bit13 = (flags amp; BIT13) > 0; // true;
bool bit16 = (flags amp; BIT16) > 0; // false;
В приведенном выше примере ADMIN и REGULAR имеют бит с номером 5 ((10 << 0) и (5 << 1) одинаковы), а GUEST — бит с номером 3.
Поэтому вы могли бы определить SiteRole с помощью побитового оператора AND , как показано выше:
UInt32 SiteRole = ...;
IsAdmin = (SiteRole amp; ADMIN) > 0;
IsRegular = (SiteRole amp; REGULAR) > 0;
IsGuest = (SiteRole amp; GUEST) > 0;
Конечно, вы также можете установить SiteRole с помощью побитового оператора OR, как показано выше:
UInt32 SiteRole = 0x00000000;
SiteRole |= ADMIN;
Реальный вопрос в том, почему ADMIN и REGULAR имеют одинаковые значения? Возможно, это ошибка.
Комментарии:
1. Спасибо, это тоже очень полезная информация… К сожалению, я не могу отметить оба как ответы.
Ответ №2:
Это операции побитового сдвига. Побитовые сдвиги используются для преобразования целочисленного значения элементов перечисления в другое число. Каждый элемент перечисления будет фактически иметь значение со сдвигом в бит. Вероятно, это метод обфускации, который аналогичен установке фиксированного целочисленного значения для каждого элемента перечисления.
Каждое целое число имеет двоичное представление (например, 0111011); сдвиг битов позволяет битам перемещаться влево (<< ) или вправо (>>) в зависимости от используемого оператора.
Например:
10 << 0 означает: 1010 (10 в двоичной форме), перемещенный с оставшимися 0 битами, равен 1010
5 << 1 означает: 101 (5 в двоичной форме) переместился на один бит влево = 1010 (добавил ноль вправо), так что 5 << 1 равно 10 (потому что 1010 представляет число 10)
и т.д.
В общем случае операцию x << y можно рассматривать как быстрый способ вычисления x * Pow(2, y);
Вы можете прочитать эту статью для получения более подробной информации о сдвиге битов в .NET http://www.blackwasp.co.uk/CSharpShiftOperators.aspx
Комментарии:
1. Хорошо, спасибо за руководство, я понимаю, что делает синтаксис, но я все еще не понимаю, зачем вам использовать его в перечислении …? Что я пытаюсь здесь получить? Это перечисление используется для определения ролей для настраиваемого атрибута авторизации. ссылка здесь: schotime.net/blog/index.php/2009/02/17 /…
2. Что ж, важно обратить внимание на
Flags
атрибут. Это используется для перечислений, значения которых являются побитовыми флагами. Двоичная форма каждого значения представляет собой флаг или набор флагов (0 и 1). Целое число имеет 32 бита, следовательно, 32 позиции. Каждая позиция может представлять флаг, и каждый 1 говорит, что флаг установлен, каждый 0 говорит, что флаг снят. Эти флаги могут соответствовать некоторым разрешениям в системе, где 1 означает, что роль имеет разрешение, 0 означает обратное. Побитовый синтаксис здесь используется либо для простой установки побитовых флагов для каждой роли, либо для запутывания (затрудняя чтение / понимание кода).