Перечисления 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?
}
Вероятно, лучше объяснить это явно, чтобы избежать путаницы!:-)