Por que as pessoas sempre usam valores de enum como 0, 1, 2, 4, 8
e não 0, 1, 2, 3, 4
?
Isso tem algo a ver com operações de bits, etc.?
Eu realmente aprecio um pequeno trecho de amostra de como isso é usado corretamente :)
[Flags]
public enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
c#
permissions
enums
flags
Pascal
fonte
fonte
|
(e&
) representam. As várias respostas pressupõem que você esteja familiarizado com isso.Respostas:
Porque eles são poderes de dois e eu posso fazer isso:
E talvez mais tarde ...
É um campo de bits, em que cada bit definido corresponde a alguma permissão (ou seja qual for o valor logicamente correspondente). Se eles fossem definidos,
1, 2, 3, ...
você não seria capaz de usar operadores bit a bit dessa maneira e obter resultados significativos. Para aprofundar ...Observe um padrão aqui? Agora, se pegarmos meu exemplo original, ou seja,
Então...
Vejo? Os bits
Read
eWrite
estão definidos, e posso verificar isso independentemente (observe também que oDelete
bit não está definido e, portanto, esse valor não transmite permissão para excluir).Ele permite armazenar vários sinalizadores em um único campo de bits.
fonte
myEnum.IsSet
. Eu sou da opinião de que esta é uma abstração completamente inútil e serve apenas para reduzir a digitação, mas mehFlags
atributo faz pouco mais do que dar a você 'impressão bonita' iirc. Você pode usar um valor enumerado como um sinalizador, independentemente da presença do atributo.0
não éfalse
;false
éfalse
. Você pode escreverif((permissions & Permissions.Write) > 0)
.(permissions & Permissions.Write) == Permissions.Write
, agora você pode usarenum.HasFlag()
Se ainda não estiver claro nas outras respostas, pense assim:
é apenas uma maneira mais curta de escrever:
Existem oito possibilidades, mas você pode representá-las como combinações de apenas quatro membros. Se houvesse dezesseis possibilidades, você poderia representá-las como combinações de apenas cinco membros. Se houvesse quatro bilhões de possibilidades, você poderia representá-las como combinações de apenas 33 membros! Obviamente, é muito melhor ter apenas 33 membros, cada um (exceto zero), um poder de dois, do que tentar nomear quatro bilhões de itens em uma enumeração.
fonte
enum
com quatro bilhões de membros. E a parte triste é que provavelmente alguém por aí já tentou.2 ** -infinity
como um poder de dois).Como esses valores representam locais de bits exclusivos em binário:
etc., então
EDITAR:
3 em binário é representado por um valor de 1 nos dois lugares. Na verdade, é o mesmo que o valor
1 | 2
. Portanto, quando você está tentando usar os locais binários como sinalizadores para representar algum estado, 3 geralmente não é significativo (a menos que exista um valor lógico que realmente seja a combinação dos dois)Para esclarecimentos adicionais, convém estender seu exemplo de enum da seguinte maneira:
Portanto, em que eu tenho
Permissions.All
, eu também tenho implicitamentePermissions.Read
,Permissions.Write
ePermissions.Delete
fonte
3
ser11
binário, ou seja, não é mapeado para um único conjunto de bits, então você perde a capacidade de mapear 1 bit em uma posição arbitrária para um valor significativo.2|3 == 1|3 == 1|2 == 3
,. Então se você tem um valor com o binário00000011
, e suas bandeiras incluídos valores1
,2
e3
, em seguida, você não saberia se esse valor representa1 and 3
,2 and 3
,1 and 2
ouonly 3
. Isso torna muito menos útil.Acho que escrever assim é mais fácil de entender e ler, e você não precisa calculá-lo.
fonte
Eles são usados para representar sinalizadores de bits, o que permite combinações de valores de enumeração. Eu acho que é mais claro se você escrever os valores em notação hexadecimal
fonte
4194304
por 2? Que tal0x400000
? É muito mais fácil reconhecer0x800000
como a resposta correta do que8388608
e também é menos propenso a erros de digitar o valor hexadecimal.0x10000
uma potência de dois? Sim, começa com 1, 2, 4 ou 8 e possui todos os 0s depois. Você não precisa traduzir mentalmente de 0x10 a 16 (embora isso provavelmente se torne uma segunda natureza eventualmente), pense nisso como "algum poder de 2".Isso é realmente mais um comentário, mas como isso não suporta a formatação, eu só queria incluir um método que empreguei para configurar as enumerações de sinalizadores:
Considero essa abordagem especialmente útil durante o desenvolvimento no caso em que você deseja manter suas bandeiras em ordem alfabética. Se você determinar que precisa adicionar um novo valor de sinalizador, basta inseri-lo em ordem alfabética e o único valor a ser alterado é o que precede agora.
Observe, no entanto, que depois que uma solução é publicada em qualquer sistema de produção (especialmente se o enum é exposto sem um acoplamento rígido, como em um serviço da Web), é altamente recomendável não alterar qualquer valor existente no enum.
fonte
Muitas respostas boas para essa aqui ... direi ... se você não gosta, ou não consegue entender facilmente o que a
<<
sintaxe está tentando expressar ... eu pessoalmente prefiro uma alternativa (e ouso dizer, estilo simples de declaração enum) ...LOG 513 == 513
Muito mais fácil (pelo menos para mim) de compreender. Alinhe os… descreva o resultado desejado, obtenha o resultado que você deseja. Não são necessários "cálculos".
fonte