С# Enums с атрибутами флагов

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

Например,

[Flags]
public enum MyColor
{
    Yellow = 1,
    Green = 2,
    Red = 4,
    Blue = 8
}

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

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

[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?
}

Наверное, лучше сказать это явно, чтобы избежать массового смятения!: -)