FlagsAttribute
appliqué à une énumération permet de combiner plusieurs valeurs de cette énumérations. Rien de nouveau pour vous (sinon, voir MSDN).
Mais de quelle façon définissez-vous les valeurs ?
[Flags]
public enum MyFlags
{
Flag1 = 0x01, // 00001
Flag2 = 0x02, // 00010
Flag3 = 0x04, // 00100
Flag4 = 0x08, // 01000
Flag5 = 0x10 // 10000
}
Jusqu’à présent, j’avais l’habitude d’utiliser la notation ci-dessus, qui est équivalente à celle-ci:
[Flags]
public enum MyFlags
{
Flag1 = 1,
Flag2 = 2,
Flag3 = 4,
Flag4 = 8,
Flag5 = 16,
}
Lorsque l’énumération est susceptible de contenir beaucoup de valeurs, aucune de ces notations n’est vraiment très pratique pour éviter une erreur.
En lisant un bouquin sur le langage C (bon ok, sur Objective-C… (c’était avant l’annonce de SWIFT, sinon vous pensez bien que j’aurai économisé mon temps)), je suis tombé sur un exemple de code avec cette notation:
[Flags]
public enum MyFlags
{
Flag1 = 1 << 0,
Flag2 = 1 << 1,
Flag3 = 1 << 2,
Flag4 = 1 << 3,
Flag5 = 1 << 4,
}
N’est-ce pas beaucoup plus clair ? Il est ainsi très simple d’éviter une collision entre deux valeurs (il n’y a qu’à suivre la séquence de 1 en 1). Je ne découvre pas l’opérateur de bits <<
mais je n’ai tout bêtement jamais pensé à l’utiliser ainsi.
Après avoir remarqué cela, j’ai rapidement cherché sur le net des articles de référence sur les énumérations et les flags en C#, je ne trouve aucun exemple de code qui utilise cette notation. Il m’a donc semblé bon de faire ce petit article qui pourra peut-être servir à d’autres développeurs aussi paresseux que moi dès qu’il s’agit de faire des maths…
[Flags]
public enum MyFlags
{
Flag1 = 1 << 0,
Flag2 = 1 << 1,
Flag3 = 1 << 2,
Flag4 = 1 << 3,
Flag5 = 1 << 4,
}
public class Program
{
public void Main()
{
var flags = MyFlags.Flag1 | MyFlags.Flag3;
Console.WriteLine("Flags: {0}\r\n{1}", flags, ConvertToBitString((int)flags));
}
static string ConvertToBitString(int n)
{
var buffer = new char[32];
var index = 31;
int i = -1;
while (++i < 32)
{
buffer[index] = (n & (1 << i)) != 0 ? '1' : '0';
index--;
}
return new string(buffer);
}
}
/* Output:
Flags: Value1, Value3
00000000000000000000000000000101
*/