c# - example - ¿Por qué alguien usaría el operador<< en una declaración enum?
enum definition c# (7)
Estaba mirando el código que tengo actualmente en mi proyecto y encontré algo como esto:
public enum MyEnum
{
open = 1 << 00,
close = 1 << 01,
Maybe = 1 << 02,
........
}
El <<
operando es el operando de cambio, que desplaza el primer operando dejado por los bits de número especificados en el segundo operando.
Pero ¿por qué alguien usaría esto en una declaración enum
?
Es igual a potencias de dos.
public enum SomeEnum
{
Enum1 = 1 << 0, //1
Enum2 = 1 << 1, //2
Enum3 = 1 << 2, //4
Enum4 = 1 << 3 //8
}
Y con tal enum tendrás una función que se ve así:
void foo(unsigned ind flags)
{
for (int = 0; i < MAX_NUMS; i++)
if (1 << i & flags)
{
//do some stuff...
//parameter to that stuff probably is i either enum value
}
}
Y llamar a esa función sería foo(Enum2 | Enum3);
y hará algo con todos los valores enum dados.
Esto es para hacer una enumeración que puedes combinar.
Lo que efectivamente significa es esto:
public enum MyEnum
{
open = 1;
close = 2;
Maybe = 4;
//...
}
Este es solo un método más a prueba de balas para crear un [Flags]
enum.
Esto se usa generalmente con bitfields, ya que está claro cuál es el patrón, elimina la necesidad de calcular manualmente los valores correctos y, por lo tanto, reduce la posibilidad de errores
[Flags]
public enum SomeBitField
{
open = 1 << 0 //1
closed = 1 << 1 //2
maybe = 1 << 2 //4
other = 1 << 3 //8
...
}
Esto te permite hacer algo como esto:
var myEnumValue = MyEnum.open | MyEnum.close;
sin necesidad de contar valores de bits de múltiplos de 2.
(Me gusta esto):
public enum MyEnum
{
open = 1,
close = 2,
Maybe = 4,
........
}
Muchas respuestas aquí que describen lo que esta mecánica te permite hacer, pero no por qué querrías usarla. Este es el por qué.
Version corta:
Esta notación ayuda cuando se interactúa con otros componentes y se comunica con otros ingenieros porque le dice explícitamente qué bit en una palabra se establece o es claro en lugar de oscurecer esa información dentro de un valor numérico.
Así que podría llamarte por teléfono y decir "Oye, ¿qué bit es para abrir el archivo?" Y tu dirías, "Bit 0". Y escribiría en mi código open = 1 << 0
. Porque el número a la derecha de <<
te dice el número de bit.
.
Versión larga:
Tradicionalmente, los bits en una palabra están numerados de derecha a izquierda, comenzando en cero. Por lo tanto, el bit menos significativo es el bit número 0 y usted cuenta a medida que avanza hacia el bit más significativo. Hay varios benefits para etiquetar bits de esta manera.
Una ventaja es que puede hablar del mismo bit independientemente del tamaño de la palabra. Por ejemplo, podría decir que tanto en la palabra de 32 bits 0x384A como en la palabra de 8 bits 0x63, se establecen los bits 6 y 1. Si numeró sus bits en la otra dirección, no podría hacer eso.
Otra ventaja es que el valor de un bit es simplemente 2 elevado a la potencia de la posición del bit. Por ejemplo, el 0101
binario tiene los bits 2 y 0 establecidos. El bit 2 aporta el valor 4 (2^2)
al número, y el bit 0 contribuye con el valor 1 (2 ^ 0). Entonces, el valor del número es, por supuesto, 4 + 1 = 5.
Esa explicación de fondo de largo recorrido nos lleva al punto: la notación <<
te dice el número de bit simplemente mirándolo.
El número 1 solo en la declaración 1 << n
es simplemente un bit único establecido en la posición de bit 0. Cuando cambia ese número a la izquierda, entonces está moviendo ese bit establecido a una posición diferente en el número. Convenientemente, la cantidad que cambia le dice el número de bit que se establecerá.
1 << 5: This means bit 5. The value is 0x20.
1 << 12: This means bit 12. The value is 0x40000.
1 << 17: This means bit 17. The value is 0x1000000.
1 << 54: This means bit 54. The value is 0x40000000000000.
(You can probably see that this notation might be helpful if
you''re defining bits in a 64-bit number)
Esta notación realmente es útil cuando interactúa con otro componente, como asignar bits en una palabra a un registro de hardware. Como si tuviera un dispositivo que se enciende cuando escribe en el bit 7. Entonces, el ingeniero de hardware escribiría una hoja de datos que dice que el bit 7 habilita el dispositivo. Y escribirías en tu código ENABLE = 1 << 7
. Tan fácil como eso.
Oh dispara. El ingeniero acaba de enviar una errata a la hoja de datos diciendo que se suponía que era el bit 15, no el bit 7. Está bien, simplemente cambie el código a ENABLE = 1 << 15
.
¿Qué pasaría si ENABLE
fuera en realidad cuando ambos bits 7 y 1 se configuraron al mismo tiempo?
ENABLE = (1 << 7) | (1 << 1)
ENABLE = (1 << 7) | (1 << 1)
.
Puede parecer extraño y obtuso al principio, pero te acostumbrarás. Y lo agradecerás si alguna vez explícitamente necesitas saber el número de bits de algo.
Para evitar escribir a mano los valores para un enum de Flags
.
public enum MyEnum
{
open = 0x01,
close = 0x02,
Maybe = 0x04,
........
}
Simplemente pretende ser una forma más limpia / más intuitiva de escribir los bits. 1, 2, 3 es una secuencia más humana que 0x1, 0x2, 0x4, etc.