Comment stocker plusieurs états dans une variable?
-
13-09-2019 - |
Question
Mon Item
objet a plusieurs états binaires qui peuvent être combinés
bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;
Je dois stocker combinaison de valeurs en cours dans une variable. La raison est que je dois stocker cette valeur dans DB. En C ++ je voudrais créer un masque de bits où un État occupe quelque peu. Est-ce une bonne pratique dans .NET?
La solution
Vous pouvez utiliser une énumération avec l'attribut Flags
:
[Flags]
enum MyStates {
CanBeSold = 1,
CanBeBought = 2,
CanBeExchanged = 4
}
Étant donné que les énumérations sont des types de données intégrales ci-dessous vous pouvez les combiner de la manière habituelle:
state = MyStates.CanBeSold | MyStates.CanBeExchanged
Notez que cela ne fonctionne que lorsque les valeurs de ENUM sont des puissances de deux (comme Doug Ferguson a fait remarquer dans un commentaire), de sorte qu'ils peuvent être combinés facilement et ne se chevauchent pas lorsque plusieurs sont ceux qui sont définis.
Vous pouvez également définir des valeurs que des combinaisons de plusieurs autres valeurs:
CanBeSoldOrBought = CanBeSold | CanBeBought
ou
CanBeSoldOrBought = 3
qui alors fonctionne comme prévu. Cela peut être vu par exemple des permissions de fichiers où ReadWrite est habituellement une combinaison de lecture et d'écriture de bits.
Et oui, c'est tout à fait une pratique courante. Le cadre lui-même utilise aussi dans plusieurs endroits.
La façon habituelle de Vérifier pour un peu particulière est alors réglée
if ((state & MyStates.CanBeSold) != 0) { ... }
Autres conseils
Créer un enum où les valeurs correspondent à des bits dans un nombre entier. Ajout de l'attribut flags vous a permis de faire des opérations plus de bits sur les valeurs ENUM.
[Flags]
public enum CanBe {
Sold = 1,
Bought = 2,
Exchanged = 4
}
Maintenant, vous pouvez simplement utiliser l'opérateur entre les valeurs:
CanBe can = CabBe.Sold | CanBe.Exchanged.
Vous pouvez ajouter un état avec le | = opérateur:
can |= CanBe.Sold;
Ou plusieurs états:
can |= CanBe.Sold | CanBe.Bought;
Vous pouvez garder un état avec l'opérateur & =:
can &= CanBe.Sold;
Ou plusieurs états:
can &= CanBe.Sold | CanBe.Bought;
Vous pouvez supprimer des états en utilisant l'opérateur ~ pour créer un complément à une valeur:
can &= ~CabBe.Bough;
Ou états seveal:
can &= ~(CabBe.Bough | CanBe.Exchanged);
Vous pouvez vérifier un état à l'aide de l'opérateur &:
if ((can & CanBe.Sold) != 0) ...
Ou plusieurs états à la fois:
if ((can & (CanBe.Sold | CanBe.Bought)) != 0) ...
Ou vérifier que plusieurs états sont tous ensemble:
if ((can & (CanBe.Sold | CanBe.Bought)) == (CanBe.Sold | CanBe.Bought)) ...
Vous pouvez le faire avec des masques de bits dans .NET aussi.
Dans votre ENUM, vous pouvez définir vos états comme valeurs
public enum ItemState { CanBeSold = 1; CanBeBought = 2; CanBeExchanged = 4 }
Ensuite, au sein de votre objet, vous pouvez le faire
if (item.State ^ ItemState.CanBeSold) ....
Vous pouvez utiliser un Flags ENUM avec chaque bit spécifié
[Flags]
enum MyStates {
CanBeSold = 0x1,
CanBeBought = 0x2,
CanBeExchanged = 0x4,
}
MyStates m_Flags;
// to set a flag:
m_Flags |= MyStates.CanBeSold;
// to unset a flag:
m_Flags &= ~MyStates.CanBeSold;