Come memorizzare diversi stati in una variabile?
-
13-09-2019 - |
Domanda
Il mio oggetto Item
ha diversi binari membri, che possono essere combinati
bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;
Ho bisogno di memorizzare la combinazione di valori in una variabile.Il motivo è che ho bisogno di memorizzare il valore in DB.In C++ vorrei creare una maschera di bit dove uno stato occupa un po'.È buona pratica .NET?
Soluzione
È possibile utilizzare un'enumerazione con l'attributo Flags
:
[Flags]
enum MyStates {
CanBeSold = 1,
CanBeBought = 2,
CanBeExchanged = 4
}
Dato che le enumerazioni sono tipi di dati integrali sotto di voi li possono combinare nel modo consueto:
state = MyStates.CanBeSold | MyStates.CanBeExchanged
Si noti che questo funziona solo quando i valori enum sono potenze di due (come Doug Ferguson sottolineato in un commento), in modo che possono essere combinati in modo semplice e non si sovrappongono quando quelli più sono impostati.
È anche possibile definire i valori come combinazioni di molteplici altri valori:
CanBeSoldOrBought = CanBeSold | CanBeBought
o
CanBeSoldOrBought = 3
che funziona quindi come ci si aspetta. Questo può essere visto ad esempio, per i permessi dei file in cui ReadWrite di solito è una combinazione di lettura e scrittura bit.
E sì, questo è abbastanza una pratica comune. Il framework stesso usa anche in più punti.
Il modo normale di controllare per un particolare bit sia impostato viene quindi
if ((state & MyStates.CanBeSold) != 0) { ... }
Altri suggerimenti
Creare un enum, dove i valori corrispondono ai bit in un numero intero.Aggiungere l'attributo Flags permesso di fare qualche bit in più operazioni sui valori enum.
[Flags]
public enum CanBe {
Sold = 1,
Bought = 2,
Exchanged = 4
}
Ora si può semplicemente utilizzare l'operatore or tra i valori:
CanBe can = CabBe.Sold | CanBe.Exchanged.
È possibile aggiungere uno stato con l'operatore|=:
can |= CanBe.Sold;
O più stati:
can |= CanBe.Sold | CanBe.Bought;
È possibile mantenere uno stato con la &= operatore:
can &= CanBe.Sold;
O più stati:
can &= CanBe.Sold | CanBe.Bought;
È possibile rimuovere uniti utilizzando il ~ operatore di creare un complemento per un valore di:
can &= ~CabBe.Bough;
O quali spiccano le ceramiche stati:
can &= ~(CabBe.Bough | CanBe.Exchanged);
Si può verificare uno stato con l'operatore&:
if ((can & CanBe.Sold) != 0) ...
O più stati contemporaneamente:
if ((can & (CanBe.Sold | CanBe.Bought)) != 0) ...
O verificare che diversi stati sono tutti insieme:
if ((can & (CanBe.Sold | CanBe.Bought)) == (CanBe.Sold | CanBe.Bought)) ...
Si può fare questo con maschere di bit in .NET troppo.
All'interno del vostro enum è possibile definire i vostri stati come valori
public enum ItemState { CanBeSold = 1; CanBeBought = 2; CanBeExchanged = 4 }
Poi all'interno del vostro oggetto, si può fare
if (item.State ^ ItemState.CanBeSold) ....
È possibile utilizzare un enum Bandiere con ogni bit specificato
[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;