El [Flags]
atributo debe usarse siempre que el enumerable represente una colección de valores posibles, en lugar de un solo valor. Tales colecciones a menudo se usan con operadores bit a bit, por ejemplo:
var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
Tenga en cuenta que el [Flags]
atributo no habilita esto por sí mismo; todo lo que hace es permitir una buena representación por el .ToString()
método:
enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
[Flags] enum SuitsFlags { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
...
var str1 = (Suits.Spades | Suits.Diamonds).ToString();
// "5"
var str2 = (SuitsFlags.Spades | SuitsFlags.Diamonds).ToString();
// "Spades, Diamonds"
También es importante tener en cuenta que [Flags]
no hace automáticamente que los valores de enumeración sean potencias de dos. Si omite los valores numéricos, la enumeración no funcionará como cabría esperar en las operaciones bit a bit, ya que de forma predeterminada los valores comienzan con 0 y se incrementan.
Declaración incorrecta
[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}
Los valores, si se declaran de esta manera, serán Amarillo = 0, Verde = 1, Rojo = 2, Azul = 3. Esto lo hará inútil como banderas.
Aquí hay un ejemplo de una declaración correcta:
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}
Para recuperar los valores distintos en su propiedad, uno puede hacer esto:
if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
// Yellow is allowed...
}
o antes de .NET 4:
if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
// Yellow is allowed...
}
if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
// Green is allowed...
}
Debajo de las sábanas
Esto funciona porque usaste poderes de dos en tu enumeración. Debajo de las cubiertas, sus valores de enumeración se ven así en binarios y ceros:
Yellow: 00000001
Green: 00000010
Red: 00000100
Blue: 00001000
Del mismo modo, después de haber configurado su propiedad AllowColors en Rojo, Verde y Azul utilizando el |
operador OR binario a nivel de bit , AllowColors se ve así:
myProperties.AllowedColors: 00001110
Entonces, cuando recupera el valor, en realidad está realizando bit a bit Y &
en los valores:
myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!
El valor Ninguno = 0
Y con respecto al uso de 0
en su enumeración, citando de MSDN:
[Flags]
public enum MyColors
{
None = 0,
....
}
Use None como el nombre de la constante enumerada de bandera cuyo valor es cero. No puede usar la constante enumerada None en una operación AND a nivel de bit para probar un indicador porque el resultado siempre es cero. Sin embargo, puede realizar una comparación lógica, no bit a bit, entre el valor numérico y la constante Ninguno enumerado para determinar si se establecen bits en el valor numérico.
Puede encontrar más información sobre el atributo flags y su uso en msdn y diseñar banderas en msdn