Поведение NET Flags атрибута

256
30 марта 2017, 17:58

Столкнулся сегодня с загадочным поведением enum с атрибутом Flags. Первый enum из проекта, только имя изменил. Второй из инета, для примера. Проблема в том, что первый enum никак не хочет складывать значения. Уже испробовал все варианты. Взял из инета проверить поведение (подумал глюк среды), так нет, второй работает нормально.

class Program
{
    // это наш 
    [Flags]
    enum LabelType
    {
        A = 0,
        B = 1,
        C  = 2
    }
     // это пример из инета
    [Flags]
    enum RenderType
    {
        None = 0x0,
        DataUri = 0x1,
        GZip = 0x2,
        ContentPage = 0x4,
        ViewPage = 0x8,
        HomePage = 0x10
    }
    static void Main(string[] args)
    {
        RenderType type = RenderType.ViewPage;
        type |= RenderType.DataUri;
        type |= RenderType.GZip;
        // type - содержит все значения
        LabelType type2 = LabelType.C;
        type2 |= LabelType.A;
        type2 |= LabelType.B;
        / type2 - содержит только В 
    }

Как видно enum фактически одинаковые. Кроме нумерации Value. Но это роли не играет, проверялось(оно и не должно влиять не результат).

Кто то сталкивался с подобным ?

Answer 1

Логично, потому что 0 - это пустой флаг. Не случайно же он там None называется.

И ещё прочитай про битовые операции, потому что чую, при добавлении следующего варианта в enum, ты в ещё одну лужу сядешь.

Answer 2

Нумерация в случае флагов сильно влияет на результат. HEX-представление используют для понятности, можно и десятичное представление использовать, но читаемость потеряется где-то после 10-го флага, это не говоря про комбинированные флаги.

Пересказывать лекции по битовым операциям и двоичному представлению не буду, просто напомню, что 1 байт это ровно 2 hex-цифры, каждая из которых задает состояние ровно 4 бит. В работе удобнее использовать именно такое представление, а не десятичное.

Флаги могут быть:

  • единичным, определяется одним битом;
  • комбинированным, определяется набором бит, длина набора зависит от базового типа enum-а;
  • пустым, значение флага 0.

С точки зрения C# и .NET типы флагов не различимы, это просто числа, но для человека такое разделение понятнее.

У пустого флага никакого особого назначения нет. Просто с помощью пустого флага можно удобно проверять отсутствие флагов в одно сравнение, вместо нескольких операций или "магических чисел" в коде.

Answer 3

Для флагов обычно используются значения по степеням двойки, как и показано в примере из интернета.

то есть в вашем случае лучше переписать так:

[Flags]
enum LabelType
{
    A = 1,
    B = 2,
    C  = 4,
}
Answer 4

Всё же перечитал про битовые поля. 0 всё-таки там нужен. В противном случае не определиться, какие флаги мы туда добавили.

READ ALSO
Как вызывать по одной форме внутри Panel?

Как вызывать по одной форме внутри Panel?

Проблема в том, что вызывая Form2 она открывается несколько раз до бесконечностиМожет есть способ открывать только один раз, и при переходе...

213
Вопрос про компоновку представлений asp.net mvc

Вопрос про компоновку представлений asp.net mvc

Подход database first, есть две модели и у каждой модели по одному представлению

240
optgroup для dropdowlist

optgroup для dropdowlist

Есть такой кусок кода

148
Ошибка при создании пользователей

Ошибка при создании пользователей

ЗдравствуйтеНеобходимо создать роли и пользователей с помощью Конфигурации ASP

196