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?

Foi útil?

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;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top