Bien souvent, je vois des déclarations enum qui utilisent des valeurs hexadécimales. Par exemple:
[Flags]
public enum MyEnum
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4,
Flag4 = 0x8,
Flag5 = 0x10
}
Quand je déclare un enum, je le déclare généralement comme ceci:
[Flags]
public enum MyEnum
{
None = 0,
Flag1 = 1,
Flag2 = 2,
Flag3 = 4,
Flag4 = 8,
Flag5 = 16
}
Y a-t-il une raison ou une raison pour laquelle certaines personnes choisissent d'écrire la valeur en hexadécimal plutôt qu'en décimal? D'après ce que je vois, il est plus facile de confondre l'utilisation de valeurs hexadécimales et d'écrire accidentellement Flag5 = 0x16
Au lieu de Flag5 = 0x10
.
Les raisonnements peuvent différer, mais je vois un avantage, c'est que l'hexadécimal vous rappelle: "Bon, nous ne traitons plus de nombres dans le monde arbitraire inventé par l'homme de la base 10. Nous avons affaire à des bits - le monde de la machine - et allez jouer selon ses règles. " Le format hexadécimal est rarement utilisé, sauf si vous traitez avec des sujets de niveau relativement bas pour lesquels la disposition de la mémoire des données est importante. Son utilisation laisse à penser que c'est la situation dans laquelle nous nous trouvons maintenant.
De plus, je ne suis pas sûr de C #, mais je sais que dans C x << y
est une constante de compilation valide. Utiliser le décalage de bits semble le plus clair:
[Flags]
public enum MyEnum
{
None = 0,
Flag1 = 1 << 0,
Flag2 = 1 << 1,
Flag3 = 1 << 2,
Flag4 = 1 << 3,
Flag5 = 1 << 4
}
Il est facile de voir qu'il s'agit de drapeaux binaires.
None = 0x0, // == 00000
Flag1 = 0x1, // == 00001
Flag2 = 0x2, // == 00010
Flag3 = 0x4, // == 00100
Flag4 = 0x8, // == 01000
Flag5 = 0x10 // == 10000
Bien que la progression le rende encore plus clair:
Flag6 = 0x20 // == 00100000
Flag7 = 0x40 // == 01000000
Flag8 = 0x80 // == 10000000
Je pense que c'est juste parce que la séquence est toujours 1,2,4,8 et ensuite ajouter un 0.
Comme vous pouvez le voir:
0x1 = 1
0x2 = 2
0x4 = 4
0x8 = 8
0x10 = 16
0x20 = 32
0x40 = 64
0x80 = 128
0x100 = 256
0x200 = 512
0x400 = 1024
0x800 = 2048
et ainsi de suite, tant que vous vous souvenez de la séquence 1-2-4-8, vous pouvez construire tous les drapeaux suivants sans avoir à vous rappeler les pouvoirs de 2
Car [Flags]
_ signifie que l’énumération est en réalité un bitfield . Avec [Flags]
vous pouvez utiliser le bit AND (&
) et OR (|
) opérateurs pour combiner les drapeaux. Lorsque vous utilisez des valeurs binaires comme celle-ci, il est presque toujours plus clair d'utiliser des valeurs hexadécimales. C'est la raison même pour laquelle nous utilisons hexadécimal en premier lieu. Chaque caractère hexadécimal correspond à exactement un quartet (quatre bits). Avec décimal, ce mappage 1 à 4 ne vaut pas.
Parce qu’il existe un moyen simple et mécanique de doubler une puissance de deux en hexadécimal. En décimal, c'est difficile. Cela nécessite une longue multiplication dans votre tête. En hex c'est un simple changement. Vous pouvez le faire jusqu’à 1UL << 63
ce que vous ne pouvez pas faire en décimal.
Parce qu'il est plus facile de suivre pour les humains où les bits sont dans le drapeau. Chaque chiffre hexadécimal peut contenir un fichier binaire de 4 bits.
0x0 = 0000
0x1 = 0001
0x2 = 0010
0x3 = 0011
... and so on
0xF = 1111
Généralement, vous souhaitez que vos indicateurs ne chevauchent pas les bits. Pour le visualiser et le mieux, utilisez les valeurs hexadécimales pour déclarer vos indicateurs.
Donc, si vous avez besoin d’indicateurs 16 bits, vous utiliserez des valeurs hexadécimales à 4 chiffres. Vous éviterez ainsi les valeurs erronées:
0x0001 //= 1 = 000000000000 0001
0x0002 //= 2 = 000000000000 0010
0x0004 //= 4 = 000000000000 0100
0x0008 //= 8 = 000000000000 1000
...
0x0010 //= 16 = 0000 0000 0001 0000
0x0020 //= 32 = 0000 0000 0010 0000
...
0x8000 //= 32768 = 1000 0000 0000 0000