The [Flags]
每当可枚举表示可能值的集合而不是单个值时,就应该使用属性。此类集合通常与按位运算符一起使用,例如:
var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
请注意,[Flags]
属性doesn't自己启用它 - 它所做的只是允许一个很好的表示.ToString()
method:
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]
does not自动使枚举值成为 2 的幂。如果省略数值,则枚举将无法按位运算中的方式工作,因为默认情况下,值从 0 开始并递增。
错误声明:
[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}
如果以这种方式声明,这些值将是黄色 = 0、绿色 = 1、红色 = 2、蓝色 = 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 转换为红色、绿色和蓝色|
操作员,允许的颜色看起来像这样:
myProperties.AllowedColors: 00001110
因此,当您检索值时,您实际上是在执行按位 AND&
关于价值观:
myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!
无 = 0 值
以及关于使用0
在你的枚举中,引用MSDN:
[Flags]
public enum MyColors
{
None = 0,
....
}
使用 None 作为其值为 0 的标志枚举常量的名称。您不能在按位 AND 运算中使用 None 枚举常量来测试标志,因为结果始终为零。但是,您可以在数值与 None 枚举常量之间执行逻辑比较,而不是按位比较,以确定是否设置了数值中的任何位。
您可以在以下位置找到有关 flags 属性及其用法的更多信息:msdn http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx and 在 msdn 上设计标志 http://msdn.microsoft.com/en-us/library/ms229062.aspx