Como armazenar vários estados em uma variável?
-
13-09-2019 - |
Pergunta
Meu objetivo Item
tem vários estados binários que podem ser combinadas
bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;
Eu preciso armazenar combinação atual de valores em uma variável. O motivo é que eu preciso para armazenar este valor no DB. Em C ++ eu iria criar um bit-máscara onde um estado ocupa algum bocado. É uma boa prática em .NET?
Solução
Você pode usar uma enumeração com o atributo Flags
:
[Flags]
enum MyStates {
CanBeSold = 1,
CanBeBought = 2,
CanBeExchanged = 4
}
Desde enumerações são tipos de dados integrais debaixo de você pode combiná-los na forma usual:
state = MyStates.CanBeSold | MyStates.CanBeExchanged
Note que isto só funciona quando os valores de enumeração são potências de dois (como Doug Ferguson apontadas em um comentário), para que possam ser combinados com facilidade e não se sobrepõem quando vários queridos estão definidos.
Você também pode definir valores como combinações de vários outros valores:
CanBeSoldOrBought = CanBeSold | CanBeBought
ou
CanBeSoldOrBought = 3
que, em seguida, também funciona como esperado. Isto pode ser visto, por exemplo, para as permissões de arquivo onde ReadWrite geralmente é uma combinação da ler e escrever pedaços.
E sim, isso é uma prática bastante comum. A própria estrutura também usa-lo em vários lugares.
A maneira usual de verificação para um determinado bit sendo conjunto é então
if ((state & MyStates.CanBeSold) != 0) { ... }
Outras dicas
Criar um enum onde os valores correspondem a bits em um inteiro. Adicionando o atributo Flags permitiu-lhe fazer algumas operações mais bits nos valores enum.
[Flags]
public enum CanBe {
Sold = 1,
Bought = 2,
Exchanged = 4
}
Agora você pode simplesmente usar o operador ou entre os valores:
CanBe can = CabBe.Sold | CanBe.Exchanged.
Você pode adicionar um estado com o | = operador:
can |= CanBe.Sold;
ou vários estados:
can |= CanBe.Sold | CanBe.Bought;
Você pode manter um estado com o & operador =:
can &= CanBe.Sold;
ou vários estados:
can &= CanBe.Sold | CanBe.Bought;
Você pode remover estados usando o operador ~ para criar um complemento para um valor:
can &= ~CabBe.Bough;
ou estados seveal:
can &= ~(CabBe.Bough | CanBe.Exchanged);
Você pode verificar a existência de um estado usando o operador &:
if ((can & CanBe.Sold) != 0) ...
Ou vários estados ao mesmo tempo:
if ((can & (CanBe.Sold | CanBe.Bought)) != 0) ...
Ou verificar que vários estados estão todos definidos:
if ((can & (CanBe.Sold | CanBe.Bought)) == (CanBe.Sold | CanBe.Bought)) ...
Você pode fazer isso com máscaras de bits em .NET também.
Dentro de sua enumeração pode definir os seus estados como valores
public enum ItemState { CanBeSold = 1; CanBeBought = 2; CanBeExchanged = 4 }
Em seguida, dentro de seu objeto, você pode fazer
if (item.State ^ ItemState.CanBeSold) ....
Você pode usar um enum Bandeiras com cada bit especificado
[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;