2009-02-09 9 views
22

que tienen cuatro banderasUtilización de operadores bit a bit sobre banderas

Current = 0x1 
Past = 0x2 
Future = 0x4 
All = 0x7 

digamos que recibo las dos banderas pasado y el futuro (setFlags(PAST | FUTURE)). ¿Cómo puedo saber si Past está en él? Del mismo modo, ¿cómo puedo decir que Current no está en él? De esa forma no tengo que probar para cada combinación posible.

Respuesta

40

Si desea que todos los bits de la máscara de prueba para que coincida con:

if((value & mask) == mask) {...} 

Si desea cualquier bit único en la máscara de prueba que coincida:

if((value & mask) != 0) {...} 

La diferencia es más evidente cuando se prueba un valor para varias cosas.

para la prueba de exclusión:

if ((value & mask) == 0) { } 
+0

¿Darías un ejemplo con el ~? – Malfist

+0

En realidad, podría no ser necesario - updatd –

-1

puede usar AND y comprobar si el resultado es el mismo que usted y con?

4
if ((flags & PAST) == PAST) 
{ 
    // PAST is there 
} 

if ((flags & CURRENT) != CURRENT) 
{ 
    // CURRENT is not there 
} 
+0

Una pena que es incorrecto (no compila) ...en C# necesita corchetes alrededor de (flags & CURRENT) –

+4

@Marc Gravell, ¿por qué publicaría este comentario y no editaría la publicación para el chico? – mmcdole

0
(value & Current) == Current 
26

En primer lugar - utilizar enumeraciones con FlagAttribute. Para eso es para eso.

[Flags] 
public enum Time 
{ 
    None = 0 
    Current = 1, 
    Past = 2, 
    Future = 4 
    All = 7 
} 

Prueba continuación, se hace así:

if ((x & Time.Past) != 0) 

O esto:

if ((x & Time.Past) == Time.Past) 

Este último va a funcionar mejor si "pasado" fue una combinación de banderas y que quería poner a prueba el centro comercial.

entorno es como esto:

x |= Time.Past; 

desarmado es así:

x &= ~Time.Past; 
+0

Corrígeme si me equivoco, creo que 1 no es apropiado para ser usado como valor de bandera? Como cualquier valor de indicador (& Operador) con 1, el resultado sigue siendo 1. – Roylee

+1

@Roylee - no, ese es un valor de indicador perfectamente normal. Corresponde exactamente a un bit. Y piénselo - por ejemplo, 4 & 1 = 0. –

+0

Icic. lo obtuve :) Entonces tienes que asegurarte de que el resto de los conjuntos de valores de bandera sean * potencia de 2 *, ¿verdad? – Roylee

9

También es posible que desee agregar un método extensión como esto

enum states { 
    Current = 0x1, 
    Past = 0x2, 
    Future = 0x4, 
    All = 0x7 
    }; 

    static bool Is(this states current, states value) { 
    return (current & value) == value; 
    } 

entonces usted puede hacer:

if(state.Is(states.Past)) { 
    // Past 
} 
0

En una adición a Marc Gravell y Vilx -...

Su enumeración marcada no debe especificar la cantidad para "Todos", solo debe incluir sus valores existentes. Esto aplica a todos los valores calculados.

[Flags] 
public enum Time 
{ 
    None = 0, 
    Current = 1, 
    Past = 2, 
    Future = 4, 
    All = Current | Past | Future 
} 

Tenga en cuenta que Vilx- eliminó el uso de hexadecimal para los valores. Esto es importante porque una vez que pasaste de 0x8 tus valores deberán cumplir con Hex. Deberías quedarte en decimales.

Cuestiones relacionadas