Почему люди всегда используют значения перечисления как, 0, 1, 2, 4, 8
а не как 0, 1, 2, 3, 4
?
Это как-то связано с битовыми операциями и т. Д.?
Я был бы очень признателен за небольшой фрагмент кода о том, как это используется правильно :)
[Flags]
public enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
c#
permissions
enums
flags
паскаль
источник
источник
|
(и&
) представляет. Различные ответы предполагают, что вы знакомы с этим.Ответы:
Потому что они являются полномочиями двух, и я могу сделать это:
И возможно позже ...
Это битовое поле, где каждый установленный бит соответствует определенному разрешению (или тому, что логически соответствует перечисляемому значению). Если бы они были определены как
1, 2, 3, ...
вы не сможете использовать побитовые операторы таким образом и получить значимые результаты. Углубиться ...Обратите внимание на шаблон здесь? Теперь, если мы возьмем мой оригинальный пример, т.е.
Затем...
Видеть? Оба
Read
иWrite
биты установлены, и я могу проверить , что независимо друг от друга (Также обратите внимание , чтоDelete
бит не установлен , и поэтому это значение не передает разрешение на удаление).Это позволяет хранить несколько флагов в одном поле битов.
источник
myEnum.IsSet
, Я придерживаюсь мнения, что это абсолютно бесполезная абстракция и служит только для сокращения набора текста, но меFlags
атрибут делает немного больше, чем дает вам «красивую печать» iirc. Вы можете использовать перечисляемое значение в качестве флага независимо от наличия атрибута.0
нетfalse
;false
естьfalse
. Вы могли бы, однако, написатьif((permissions & Permissions.Write) > 0)
.(permissions & Permissions.Write) == Permissions.Write
теперь вы можете использоватьenum.HasFlag()
Если это все еще не ясно из других ответов, подумайте об этом так:
это просто более короткий способ написать:
Есть восемь возможностей, но вы можете представлять их как комбинации только четырех участников. Если бы было шестнадцать вариантов, вы могли бы представлять их как комбинации только пяти участников. Если бы было четыре миллиарда возможностей, вы могли бы представлять их как комбинации только из 33 участников! Очевидно, что гораздо лучше иметь только 33 члена, каждый (кроме нуля) со степенью двойки, чем пытаться назвать четыре миллиарда предметов в перечислении.
источник
enum
с четырьмя миллиардами членов. И грустная часть, вероятно, кто-то там попробовал это.2 ** -infinity
степень двойки).Поскольку эти значения представляют уникальные местоположения битов в двоичном коде:
и т.д., так
РЕДАКТИРОВАТЬ:
3 в двоичном виде представлен значением 1 как в одном, так и в двойном разрядах. Это на самом деле так же, как значение
1 | 2
. Поэтому, когда вы пытаетесь использовать двоичные места в качестве флагов для представления некоторого состояния, 3 обычно не имеет смысла (если нет логического значения, которое на самом деле является комбинацией двух)Для дальнейшего пояснения вы можете расширить пример перечисления следующим образом:
Поэтому в меня
Permissions.All
, я также имею неявныйPermissions.Read
,Permissions.Write
иPermissions.Delete
источник
3
это11
двоичный файл, т. Е. Он не отображается ни на один установленный бит, поэтому вы теряете возможность отображать 1 бит в произвольной позиции на значащее значение.2|3 == 1|3 == 1|2 == 3
. Так что если у вас есть значение с двоичной00000011
, и ваши флаги включены значения1
,2
и3
, то вы не знаете , если это значение представляет собой1 and 3
,2 and 3
,1 and 2
илиonly 3
. Это делает его намного менее полезным.Я думаю, что писать, как это легче понять и прочитать, и вам не нужно рассчитывать это.
источник
Они используются для представления битовых флагов, которые допускают комбинации значений перечисления. Я думаю, что будет понятнее, если вы напишите значения в шестнадцатеричной записи
источник
4194304
на 2? Как насчет0x400000
? Гораздо легче распознать0x800000
правильный ответ, чем8388608
, а также менее подвержен ошибкам при вводе шестнадцатеричного значения.0x10000
сила двух? Да, он начинается с 1, 2, 4 или 8 и имеет все 0 после. Вам не нужно мысленно переводить 0x10 в 16 (хотя в конечном итоге это, вероятно, станет второй натурой), просто подумайте об этом, как о «некоторой степени 2».Это действительно больше комментарий, но так как он не поддерживает форматирование, я просто хотел включить метод, который я использовал для настройки перечисления флагов:
Я считаю, что этот подход особенно полезен во время разработки, если вы хотите поддерживать свои флаги в алфавитном порядке. Если вы решите, что вам нужно добавить новое значение флага, вы можете просто вставить его в алфавитном порядке, и единственное значение, которое вам нужно изменить, это то, которое ему предшествует.
Однако обратите внимание, что после публикации решения в любой производственной системе (особенно, если перечисление предоставляется без жесткой связи, например, через веб-службу), тогда настоятельно рекомендуется не изменять любое существующее значение в перечислении.
источник
Множество хороших ответов на этот вопрос ... я просто скажу ... если вам не нравится, или вы не можете легко понять, что
<<
синтаксис пытается выразить .. Я лично предпочитаю альтернативу (и, смею сказать, простой стиль декларации перечисления) ...LOG 513 == 513
Гораздо проще (по крайней мере, для себя) понять. Выстроите их в ряд ... опишите результат, который вы хотите, получите результат, который вы ХОТИТЕ. Никаких "вычислений" не требуется.
источник