当可枚举表示可能值的集合而不是单个值时,应使用[Flags] 属性。此类集合通常与位运算符一起使用,例如:
var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
请注意,[Flags] 属性不会自行启用 - 它所做的只是允许通过 .ToString() 方法进行良好的表示:
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"
同样重要的是要注意[Flags] 不会自动将枚举值设为 2 的幂。如果省略数值,枚举将不会像人们期望的那样在按位运算中工作,因为默认情况下,值从 0 开始并递增。
不正确的声明:
[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}
如果以这种方式声明,值将是 Yellow = 0、Green = 1、Red = 2、Blue = 3。这将使它无法用作标志。
以下是正确声明的示例:
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}
要检索属性中的不同值,可以这样做:
if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
// Yellow is allowed...
}
或在 .NET 4 之前:
if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
// Yellow is allowed...
}
if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
// Green is allowed...
}
幕后
之所以有效,是因为您在枚举中使用了 2 的幂。在幕后,您的枚举值在二进制 1 和 0 中如下所示:
Yellow: 00000001
Green: 00000010
Red: 00000100
Blue: 00001000
同样,在您使用二进制位 OR | 运算符将属性 AllowedColors 设置为红色、绿色和蓝色后,AllowedColors 如下所示:
myProperties.AllowedColors: 00001110
因此,当您检索值时,您实际上是在对这些值执行按位 AND &:
myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!
None = 0 值
关于在您的枚举中使用0,引用MSDN:
[Flags]
public enum MyColors
{
None = 0,
....
}
使用 None 作为其值为 0 的标志枚举常量的名称。 您不能在按位与运算中使用 None 枚举常量来测试标志,因为结果始终为零。但是,您可以在数值和None 枚举常量,用于确定数值中是否设置了任何位。
您可以在msdn 和designing flags at msdn 找到有关标志属性及其用法的更多信息