Перечисления C# с атрибутом Flags

Мне было интересно, если Enums с атрибутом Flag в основном используются для побитовых операций, почему не компиляторы автоматически генерируют значения, если значения enum не определены.

Например,

[Flags]
публичное перечисление MyColor
{
    Желтый = 1,
    Зеленый = 2,
    Красный = 4,
    Синий = 8
}

Было бы полезно, если значения 1,2,4,8 генерируются автоматически, если они не назначены. Хотелось бы узнать ваши мысли по этому поводу.

4 ответа

Это немного проще:

[Flags]
public enum MyColor
{
    Yellow = 1<<0,
    Green = 1<<1,
    Red = 1<<2,
    Blue = 1<<3
}

Они, вероятно, могли бы, но с компилятором такого размера они должны учитывать время и ресурсы, необходимые для реализации чего-то против потенциальной выгоды, особенно с синтаксическим сахаром, подобным этому. И это просто синтаксический сахар, потому что вы можете написать его вручную.

Я ожидаю, что это потому, что экземпляр FlagsAttribute компилируется вместе или после Enum. То есть украшение объекта с помощью атрибута (например, [Flags]) вызывает создание объекта атрибута, он не изменяет базовый объект фундаментальным образом.

Кроме того, часть хранимой информации (для реализации атрибута во время выполнения) представляет собой объект, к которому он относится. Может случиться так, что перечисление сущности должно быть скомпилировано до его атрибутов, поэтому атрибут не может повлиять на сущность, к которой он относится (в данном случае перечисление). Я не знаю, это утверждение, чтобы быть правдой, это просто предположение.

Большой вывод - атрибуты, такие как [Flags], на самом деле являются самими сущностями, а не модификациями декорированного типа.

Я думаю, что это, помимо прочего, сводится к огромному заблуждению о том, какой будет первая ценность. Рассматривать:

[Flags]
public enum MyColor
{
    Yellow,
    Green,
    Red,
    Blue
 }

public class SomeClass
{
  public MyColor SomeColor;  // Yellow or undefined by default?
}

Когда создается экземпляр класса, все его поля обычно просто обнуляются (ссылки становятся нулевыми, а значения - нулевыми). Но если первое значение будет одним, то компилятору придется обрабатывать перечисления Flag иначе, чем что-либо еще.

Итак, учитывая это, а также тот факт, что очень полезно иметь возможность обнуления битового поля, мы приходим к выводу, что первое поле должно фактически быть нулевым:

[Flags]
public enum MyColor
{
    Black,   //0
    Yellow,  //1
    Green,   //2
    Red,     //3
    Blue     //4
}

Но я предполагаю, что не многие люди поймут это (без комментариев выше). И более сложные вещи возникнут тоже:

[Flags]
public enum MyColor
{
    Black,
    Red,
    Green,
    Blue,
    Magenta = Red | Blue,
    Yellow = Red | Green | Blue,
    SomeOtherColor  // now what would the value of this automatically be?
}

Вероятно, лучше объяснить это явно, чтобы избежать путаницы!:-)

Другие вопросы по тегам