2012-09-19 13 views
12

Puede ser una pregunta fácil y simple, pero todavía tengo un poco de confusión por la razón por la cual se decide utilizar bitwise OR. Suponga que tengo una clase A con cuatro campos:Por qué se usa el operador OR bit a bit en la enumeración de indicador con el significado AND

class A 
{ 
    private int Field1; 
    private static int Field2; 
    public int Field3; 
    public static int Field4; 
} 

Y el uso de Reflection para obtener campos:

var fields = typeof (A).GetFields(BindingFlags.Public | BindingFlags.Static); 

Si usted es novato con Reflection y no saben la manera cómo utilizar BindingFlags, la El pensamiento lógico inicial en su cabeza sería:

Esta línea seleccionará todos los campos estáticos O públicos porque se usa O a nivel de bits. Y el Resultado esperado que piensa:

Field2 
Field3 
Field4 

Pero al golpear F5, el resultado será totalmente diferente, bit a bit OR obras como AND:

Field4 

por qué no utilizar operador AND que podría seguir con la pensamiento lógico de esta manera:

var fields = typeof (A).GetFields(BindingFlags.Public & BindingFlags.Static); 

encontré palabras MSDN:

la operación OR bit a bit utilizado para combinar las banderas se podría considerar un concepto avanzado en algunas circunstancias que no deberían ser necesarios para tareas sencillas.

Por favor, podría alguien explicar el concepto avance aquí en forma sencilla para la comprensión?

+1

'OR' parece ser el concepto correcto aquí cuando se considera la diferencia entre O inclusivo y exclusivo. En este caso, el 'OR 'es inclusivo, lo mismo que decir" recoger algunos artículos de la tienda que contienen huevos o jamón ". Eso es diferente a decir "que contienen huevos Y jamón". –

+0

en [MSDN] (http://msdn.microsoft.com/en-us/library/6ztex2dc.aspx) lea: debe especificar BindingFlags.Instance ** o ** BindingFlags.Static para obtener un retorno. . Entonces, ¿puede ser que no pueda listar la instancia ** y ** estática al mismo tiempo ... ?? – tschmit007

+0

@ tschmit007: ¿Qué tiene eso que ver con la pregunta? –

Respuesta

25

Consulte al final para obtener un breve resumen.

Respuesta larga:

OR bit a bit es la combinación de los bits de las banderas de enumeración.

Ejemplo:

  • BindingFlags.Public tiene el valor de 16 o 10000 (binario)
  • BindingFlags.Static tiene el valor de 8 o 1000 (binario)

OR bit a bit combina estos como la siguiente :

10000 
01000 
-- 
11000 --> 24 

bitwise Y se combinarían lik e esto:

10000 
01000 
-- 
00000 --> 0 

Eso es un concepto muy básico de Banderas:
Cada valor es una potencia de dos, por ejemplo,:

  • 1 = 2^0
  • 2 = 2^1
  • 4 = 2^2
  • 8 = 2^3
  • etc.

Su representación bit es siempre una 1 y el resto ceros :

decimal | binary 
1  | 0001 
2  | 0010 
4  | 0100 
8  | 1000 

La combinación de cualquiera de ellos utilizando bits Y AND siempre llevaría a 0 ya que no hay 1 en la misma posición. Bitwise AND daría lugar a una pérdida de información completa.

Por otra parte, Bitwise OR siempre dará como resultado un resultado no ambiguo. Por ejemplo, cuando tiene (binario) 1010 (decimal 10), sabe que originalmente fue 8 y 2. No hay otra posibilidad de que se haya creado 10.
Como dijo defecto, el método que llamó más tarde puede extraer esta información utilizando el operador AND:

if(10 & 8 == 8) // value 8 was set 

La operación OR en este caso es básicamente un vehículo para transportar los valores al método que está llamando.
Lo que hace este método con estos valores no tiene nada que ver con el uso de OR a nivel de bits.
Puede requerir internamente que TODOS los indicadores pasados ​​coincidan, como es el caso del GetFields. Pero también podría requerir que coincida solo una de las banderas aprobadas.

Para usted como una persona que llama, la siguiente sería equivalente:

var requiredFlags = new List<BindingFlags>(); 
requiredFlags.Add(BindingFlags.Public); 
requiredFlags.Add(BindingFlags.Static); 
typeof (A).GetFields(requiredFlags); 

Ahora que no se compila como GetFields no proporciona tal sobrecarga, pero el significado sería el mismo que el de su código.

Para resumir las cosas (TL; DR):

AND bit a bit no tiene nada que ver con el Y lógico
OR bit a bit no tiene nada que ver con el booleano OR

+1

que ** más tarde ** se usará con el operador '&' como 'if (userArgument & BindingFlags.Public) {/ * agregar al valor de retorno * /}' – Default

2

se está utilizando la enumeración bandera para representar un conjunto de condiciones booleanas.

En su ejemplo, se debe cumplir cada condición booleana para que se devuelva el campo correspondiente.

Las enumeraciones de indicador son simplemente valores integrales que obedecen las reglas binarias habituales para anding y oring, por lo que para establecer varios bits debe O BIEN juntos los valores que representan esos bits.

Una vez que lo haya hecho, tiene una enumeración de indicador con el conjunto de bits apropiado.

El problema que está teniendo es que está combinando dos conceptos diferentes: La forma en que se construye el conjunto de condiciones booleanas para una enumeración de indicador es un concepto. La forma en que se utiliza la enumeración de la bandera (o lo que representa) es un concepto diferente.

El primero usa O para construir el conjunto de condiciones booleanas. Este último dice que cada bit representa una condición booleana que debe cumplirse.

1

Los implementadores de GetFields() eligieron interpretar la combinación de varios indicadores ORed como una combinación Y de los criterios seleccionados.

Lo cual tiene sentido ya que siempre puede soltar un criterio si no desea el filtro adicional.

Cuestiones relacionadas