Редактировать: Кажется, большинство людей неправильно поняли мой вопрос.
Я знаю, как работает enum, и я знаю бинарный файл. Мне интересно, , почему перечисления с атрибутом [Flags] созданы так, как они есть.
Оригинальный пост:
Это может быть дубликат, но я не нашел других сообщений, так что здесь.
Могу поспорить, что за этим стоит какое-то хорошее объяснение, я нахожу это немного подверженным ошибкам.
[Flag]
public enum Flagged
{
One, // 0
Two, // 1
Three, // 2
Four, // 3
}
Flagged f; // Defaults to Flagged.One = 0
f = Flagged.Four;
(f & Flagged.One) != 0; // Sure.. One defaults to 0
(f & Flagged.Two) != 0; // 3 & 1 == 1
(f & Flagged.Three) != 0; // 3 & 2 == 2
Разве не было бы больше смысла, если бы он сделал что-то подобное?
[Flag]
public enum Flagged
{
One = 1 << 0, // 1
Two = 1 << 1, // 2
Three = 1 << 2, // 4
Four = 1 << 3, // 8
}
Flagged f; // Defaults to 0
f = Flagged.Four;
(f & Flagged.One) != 0; // 8 & 1 == 0
(f & Flagged.Two) != 0; // 8 & 2 == 0
(f & Flagged.Three) != 0; // 8 & 4 == 0
(f & Flagged.Four) != 0; // 8 & 8 == 8
Конечно .. Я не совсем уверен, как он должен обрабатывать пользовательские флаги, подобные этому
[Flag]
public enum Flagged
{
One, // 1
Two, // 2
LessThanThree = One | Two,
Three, // 4? start from Two?
LessThanFour = Three | LessThanThree,
Three, // 8? start from Three?
}
Спецификация дает некоторые рекомендации
Определите константы перечисления в степенях двух, то есть 1, 2, 4, 8 и т. Д. Это означает, что отдельные флаги в комбинированных константах перечисления не перекрываются.
Но, возможно, это следует сделать автоматически, так как я уверен, что вы никогда не захотите, чтобы мой первый пример появился. Пожалуйста, просветите меня:)