Ответ 1
Это немного проще:
[Flags]
public enum MyColor
{
Yellow = 1<<0,
Green = 1<<1,
Red = 1<<2,
Blue = 1<<3
}
Мне было интересно, используются ли атрибуты Enums with Flag для побитовых операций, почему компиляторы не автогенерируют значения, если значения перечисления не определены.
Например,
[Flags] public enum MyColor { Yellow = 1, Green = 2, Red = 4, Blue = 8 }
Было бы полезно, если значения 1,2,4,8 автогенерируются, если они не назначены. Хотелось бы узнать ваши мысли об этом.
Это немного проще:
[Flags]
public enum MyColor
{
Yellow = 1<<0,
Green = 1<<1,
Red = 1<<2,
Blue = 1<<3
}
Возможно, они могли бы, но с компилятором такого размера они должны учитывать время и ресурсы, необходимые для реализации чего-то против потенциальной выгоды, особенно с таким синтаксическим сахаром. И это просто синтаксический сахар, потому что вы можете написать его вручную.
Я ожидаю, что это связано с тем, что экземпляр FlagsAttribute скомпилируется рядом или после Enum. То есть украшение объекта атрибутом (например, [Флаги]) вызывает создание объекта атрибута, он не модифицирует базовый объект фундаментальным способом.
Кроме того, часть хранимой информации (для создания экземпляра атрибута времени выполнения) является объектом, к которому он относится. Возможно, что перечисление объекта должно быть скомпилировано перед его атрибутами, поэтому атрибут не может повлиять на сущность, на которую он ссылается (в этом случае перечисление). Я не знаю, что это утверждение верно, это просто предположение.
Большой отрыв - это атрибуты, такие как [Флаги], фактически являются сущностями, а не модификациями декорированного типа.
Я думаю, что это, между прочим, сводилось бы к огромной путанице того, что будет первым значением. Рассмотрим:
[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?
}
Наверное, лучше сказать это явно, чтобы избежать массового смятения!: -)