Pourquoi les gens utilisent-ils toujours des valeurs d'énumération comme 0, 1, 2, 4, 8
et non 0, 1, 2, 3, 4
?
Cela a-t-il quelque chose à voir avec les opérations sur les bits, etc.?
J'apprécierais vraiment un petit extrait de code sur la façon dont cela est utilisé correctement :)
[Flags]
public enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
c#
permissions
enums
flags
Pascal
la source
la source
|
(et&
) représentent. Les différentes réponses supposent que vous la connaissez.Réponses:
Parce qu'ils sont des pouvoirs de deux et que je peux le faire:
Et peut-être plus tard ...
C'est un champ de bits, où chaque bit défini correspond à une autorisation (ou à toute autre valeur à laquelle correspond logiquement la valeur énumérée). Si ceux-ci étaient définis comme cela,
1, 2, 3, ...
vous ne seriez pas en mesure d'utiliser des opérateurs au niveau du bit de cette façon et d'obtenir des résultats significatifs. Pour approfondir ...Remarquez un modèle ici? Maintenant, si nous prenons mon exemple original, à savoir,
Ensuite...
Voir? Les bits
Read
etWrite
sont tous deux définis, et je peux le vérifier indépendamment (notez également que leDelete
bit n'est pas défini et que cette valeur ne transmet donc pas l'autorisation de suppression).Il permet de stocker plusieurs indicateurs dans un seul champ de bits.
la source
myEnum.IsSet
. Je suis d'avis que c'est une abstraction complètement inutile et ne sert qu'à réduire la frappe, mais mehFlags
attribut ne fait guère plus que vous donner une «jolie impression» iirc. Vous pouvez utiliser une valeur énumérée comme indicateur quelle que soit la présence de l'attribut.0
n'est pasfalse
;false
estfalse
. Vous pourriez cependant écrireif((permissions & Permissions.Write) > 0)
.(permissions & Permissions.Write) == Permissions.Write
, vous pouvez maintenant utiliserenum.HasFlag()
Si ce n'est toujours pas clair d'après les autres réponses, pensez-y comme ceci:
est juste une manière plus courte d'écrire:
Il existe huit possibilités, mais vous pouvez les représenter sous forme de combinaisons de quatre membres seulement. S'il y avait seize possibilités, vous pourriez les représenter comme des combinaisons de seulement cinq membres. S'il y avait quatre milliards de possibilités, vous pourriez les représenter comme des combinaisons de seulement 33 membres! Il est évidemment préférable de n'avoir que 33 membres, chacun (sauf zéro) une puissance de deux, que d'essayer de nommer quatre milliards d'éléments dans une énumération.
la source
enum
avec quatre milliards de membres. Et le plus triste, c'est que quelqu'un l'a probablement essayé.2 ** -infinity
comme une puissance de deux).Parce que ces valeurs représentent des emplacements de bits uniques en binaire:
etc., donc
ÉDITER:
3 en binaire est représenté par une valeur de 1 à la fois à la place des unités et à la place des deux. C'est en fait la même que la valeur
1 | 2
. Ainsi, lorsque vous essayez d'utiliser les emplacements binaires comme indicateurs pour représenter un état, 3 n'est généralement pas significatif (à moins qu'il n'y ait une valeur logique qui est en fait la combinaison des deux)Pour plus de précisions, vous pouvez étendre votre exemple d'énumération comme suit:
Par conséquent , dans je
Permissions.All
, j'ai aussi implicitementPermissions.Read
,Permissions.Write
etPermissions.Delete
la source
3
est11
binaire, c'est-à-dire qu'il ne correspond pas à un seul bit défini, vous perdez donc la possibilité de mapper 1 bit dans une position arbitraire à une valeur significative.2|3 == 1|3 == 1|2 == 3
. Donc , si vous avez une valeur binaire avec00000011
, et vos drapeaux indiquaient des valeurs1
,2
et3
, alors vous ne savez pas si cette valeur représente1 and 3
,2 and 3
,1 and 2
ouonly 3
. Cela le rend beaucoup moins utile.Je pense qu'écrire comme ça est plus facile à comprendre et à lire, et vous n'avez pas besoin de le calculer.
la source
Ceux-ci sont utilisés pour représenter des indicateurs de bits qui permettent des combinaisons de valeurs d'énumération. Je pense que c'est plus clair si vous écrivez les valeurs en notation hexadécimale
la source
4194304
par 2? Et pourquoi pas0x400000
? Il est beaucoup plus facile à reconnaître0x800000
comme la bonne réponse que8388608
, et il est également moins sujet aux erreurs de taper la valeur hexadécimale.0x10000
qu'une puissance de deux? Oui, il commence par 1, 2, 4 ou 8 et a ensuite tous les 0. Vous n'avez pas besoin de traduire mentalement 0x10 en 16 (bien que cela devienne probablement une seconde nature), pensez simplement à "une puissance de 2".C'est vraiment plus un commentaire, mais comme cela ne prendrait pas en charge le formatage, je voulais simplement inclure une méthode que j'ai utilisée pour configurer les énumérations d'indicateurs:
Je trouve cette approche particulièrement utile lors du développement dans le cas où vous souhaitez conserver vos drapeaux par ordre alphabétique. Si vous décidez que vous devez ajouter une nouvelle valeur d'indicateur, vous pouvez simplement l'insérer par ordre alphabétique et la seule valeur que vous devez modifier est celle qu'elle précède maintenant.
Notez, cependant, qu'une fois qu'une solution est publiée sur n'importe quel système de production (en particulier si l'énumération est exposée sans un couplage étroit, comme sur un service Web), il est fortement déconseillé de modifier toute valeur existante dans l'énumération.
la source
Il y a beaucoup de bonnes réponses à celle-ci… Je vais juste dire .. si vous n'aimez pas, ou ne pouvez pas facilement saisir ce que la
<<
syntaxe essaie d'exprimer .. Personnellement, je préfère une alternative (et oserais-je dire, un style de déclaration d'énumération simple ) …LOG 513 == 513
Tellement plus facile (pour moi du moins) à comprendre. Alignez-les… décrivez le résultat que vous désirez, obtenez le résultat que vous VOULEZ .. Aucun «calcul» nécessaire.
la source