L' [Flags]
attribut doit être utilisé chaque fois que l'énumérable représente une collection de valeurs possibles, plutôt qu'une seule valeur. Ces collections sont souvent utilisées avec des opérateurs au niveau du bit, par exemple:
var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
Notez que l' [Flags]
attribut ne permet pas cela par lui-même - tout ce qu'il fait est de permettre une belle représentation par la .ToString()
méthode:
enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
[Flags] enum SuitsFlags { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
...
var str1 = (Suits.Spades | Suits.Diamonds).ToString();
// "5"
var str2 = (SuitsFlags.Spades | SuitsFlags.Diamonds).ToString();
// "Spades, Diamonds"
Il est également important de noter que les valeurs d'énumération [Flags]
ne sont pas automatiquement égales à deux. Si vous omettez les valeurs numériques, l'énumération ne fonctionnera pas comme on pourrait s'y attendre dans les opérations au niveau du bit, car par défaut, les valeurs commencent par 0 et incrémentent.
Déclaration incorrecte:
[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}
Les valeurs, si elles sont déclarées de cette façon, seront Jaune = 0, Vert = 1, Rouge = 2, Bleu = 3. Cela le rendra inutile en tant que drapeaux.
Voici un exemple de déclaration correcte:
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}
Pour récupérer les valeurs distinctes de votre propriété, on peut le faire:
if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
// Yellow is allowed...
}
ou avant .NET 4:
if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
// Yellow is allowed...
}
if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
// Green is allowed...
}
Sous les couvertures
Cela fonctionne parce que vous avez utilisé des pouvoirs de deux dans votre énumération. Sous les couvertures, vos valeurs d'énumération ressemblent à ceci en binaires et en zéros:
Yellow: 00000001
Green: 00000010
Red: 00000100
Blue: 00001000
De même, une fois que vous avez défini votre propriété AllowedColors sur Rouge, Vert et Bleu à l'aide de l' |
opérateur binaire OR au niveau du bit , AllowedColors ressemble à ceci:
myProperties.AllowedColors: 00001110
Ainsi, lorsque vous récupérez la valeur que vous effectuez réellement au niveau du bit ET &
sur les valeurs:
myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!
La valeur None = 0
Et concernant l'utilisation de 0
dans votre énumération, citant MSDN:
[Flags]
public enum MyColors
{
None = 0,
....
}
Utilisez None comme nom de la constante énumérée d'indicateur dont la valeur est zéro. Vous ne pouvez pas utiliser la constante énumérée None dans une opération AND au niveau du bit pour tester un indicateur car le résultat est toujours zéro. Cependant, vous pouvez effectuer une comparaison logique, et non pas au niveau du bit, entre la valeur numérique et la constante énumérée Aucune pour déterminer si des bits de la valeur numérique sont définis.
Vous pouvez trouver plus d'informations sur l'attribut flags et son utilisation sur msdn et sur la conception de flags sur msdn