VB.NET синтаксис объявления перечисления

#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 означает обратное. Побитовый синтаксис здесь используется либо для простой установки побитовых флагов для каждой роли, либо для запутывания (затрудняя чтение / понимание кода).