The [Flags]
attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value.
(每当枚举表示可能值的集合而不是单个值时,应使用[Flags]
属性。)
Such collections are often used with bitwise operators, for example: (此类集合通常与按位运算符一起使用,例如:)
var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
Note that the [Flags]
attribute doesn't enable this by itself - all it does is allow a nice representation by the .ToString()
method:
(请注意, [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"
It is also important to note that [Flags]
does not automatically make the enum values powers of two.
(同样重要的是要注意[Flags]
不会自动使枚举值的幂为2。)
If you omit the numeric values, the enum will not work as one might expect in bitwise operations, because by default the values start with 0 and increment. (如果省略数字值,则枚举将无法按位操作,因为默认情况下,该值从0开始并递增。)
Incorrect declaration:
(不正确的声明:)
[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}
The values, if declared this way, will be Yellow = 0, Green = 1, Red = 2, Blue = 3. This will render it useless as flags.
(如果以此方式声明,则这些值将为Yellow = 0,Green = 1,Red = 2,Blue =3。这将使其变为无用的标志。)
Here's an example of a correct declaration:
(这是正确声明的示例:)
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}
To retrieve the distinct values in your property, one can do this:
(要检索属性中的不同值,可以执行以下操作:)
if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
// Yellow is allowed...
}
or prior to .NET 4:
(或.NET 4之前的版本:)
if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
// Yellow is allowed...
}
if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
// Green is allowed...
}
Under the covers
(掩护下)
This works because you used powers of two in your enumeration.
(之所以可行,是因为您在枚举中使用了2的幂。)
Under the covers, your enumeration values look like this in binary ones and zeros: (在幕后,您的枚举值看起来像这样的二进制1和0:)
Yellow: 00000001
Green: 00000010
Red: 00000100
Blue: 00001000
Similarly, after you've set your property AllowedColors to Red, Green and Blue using the binary bitwise OR |
(同样,在使用二进制按位OR |
将属性AllowedColors设置为Red,Green和Blue之后|
)
operator, AllowedColors looks like this: (运算符, AllowedColors看起来像这样:)
myProperties.AllowedColors: 00001110
So when you retrieve the value you are actually performing bitwise AND &
on the values:
(因此,当您检索该值时,实际上是对这些值执行按位与&
:)
myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!
The None = 0 value
(无= 0值)
And regarding the use of 0
in your enumeration, quoting from MSDN:
(关于在枚举中使用0
,引用MSDN:)
[Flags]
public enum MyColors
{
None = 0,
....
}
Use None as the name of the flag enumerated constant whose value is zero.
(使用None作为值为零的标志枚举常量的名称。)
You cannot use the None enumerated constant in a bitwise AND operation to test for a flag because the result is always zero. (您不能在按位与运算中使用None枚举常量来测试标志,因为结果始终为零。)
However, you can perform a logical, not a bitwise, comparison between the numeric value and the None enumerated constant to determine whether any bits in the numeric value are set. (但是,您可以在数值和None枚举常量之间进行逻辑比较而不是按位比较,以确定是否设置了数值中的任何位。)
You can find more info about the flags attribute and its usage at msdn and designing flags at msdn
(您可以在msdn上找到有关flags属性及其用法以及在msdn上 设计标志的更多信息。)