Eu tenho uma enumeração de bandeira abaixo.
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
Não posso fazer com que a declaração if seja verdadeira.
FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;
if (testItem == FlagTest.Flag1)
{
// Do something,
// however This is never true.
}
Como posso fazer isso verdade?
None
sinalizador com um valor zero. Consulte msdn.microsoft.com/pt-br/library/vstudio/…&
operador de comparação,|
é como uma adição:1|2=3
,5|2=7
,3&2=2
,7&2=2
,8&2=0
.0
avalia parafalse
, tudo o mais paratrue
.Respostas:
No .NET 4, há um novo método Enum.HasFlag . Isso permite que você escreva:
que é muito mais legível, IMO.
A fonte .NET indica que isso executa a mesma lógica que a resposta aceita:
fonte
Enum
classe.(testItem & FlagTest.Flag1)
é uma operação AND bit a bit.FlagTest.Flag1
é equivalente a001
enumeração de OP. Agora vamos dizer quetestItem
tem Flag1 e Flag2 (então é bit a bit101
):fonte
Para aqueles que têm problemas para visualizar o que está acontecendo com a solução aceita (que é essa),
testItem
(conforme a pergunta) é definido como,Então, na instrução if, o lado esquerdo da comparação é,
E a instrução if completa (que é avaliada como verdadeira se
flag1
estiver configuradatestItem
),fonte
@ phil-devaney
Observe que, exceto nos casos mais simples, o Enum.HasFlag acarreta uma penalidade de alto desempenho em comparação à gravação manual do código. Considere o seguinte código:
Mais de 10 milhões de iterações, o método de extensão HasFlags ocupa 4793 ms, em comparação com os 27 ms da implementação padrão em bits.
fonte
(«flag var» & «flag value») != 0
não funciona para mim. A condição sempre falha e meu compilador (Mono 2.6.5 do Unity3D) relata um "aviso CS0162: Código inacessível detectado" quando usado em um arquivoif (…)
.… = 1, … = 2, … = 4
nos valores enum é criticamente importante ao usar[Flags]
. Eu estava assumindo que ele iniciaria as entradas1
e avançaria pelos Po2s automaticamente. O comportamento parece consistente no MS .NET e no Mono datado do Unity. Minhas desculpas por colocar isso em você.Eu configurei um método de extensão para fazer isso: questão relacionada .
Basicamente:
Então você pode fazer:
Aliás, a convenção que uso para enumerações é singular para padrão e plural para sinalizadores. Dessa forma, você sabe pelo nome do enum se ele pode conter vários valores.
fonte
HasFlag
extensão.Mais um conselho ... Nunca faça a verificação binária padrão com a bandeira cujo valor é "0". Sua verificação nesta bandeira será sempre verdadeira.
Se você checar o parâmetro de entrada com base em FullInfo - você obtém:
bPRez sempre será verdadeiro como QUALQUER COISA & 0 sempre == 0.
Em vez disso, você deve simplesmente verificar se o valor da entrada é 0:
fonte
fonte
Para operações de bit, você precisa usar operadores bit a bit.
Isso deve fazer o truque:
Edit: Corrigido meu if check - voltei às minhas maneiras de C / C ++ (obrigado a Ryan Farley por apontá-lo)
fonte
Em relação à edição. Você não pode fazer isso verdade. Sugiro que você agrupe o que deseja em outra classe (ou método de extensão) para se aproximar da sintaxe necessária.
ie
fonte
Tente o seguinte:
Basicamente, seu código está perguntando se ter os dois sinalizadores definidos é o mesmo que ter um sinalizador definido, o que é obviamente falso. O código acima deixará apenas o bit Flag1 definido, se estiver definido, e compara esse resultado ao Flag1.fonte
mesmo sem [Flags], você poderia usar algo como isto
ou se você tiver um valor zero enum
fonte