[英]How does c# flags attribute enum bit combining work?
枚举的Flags属性允许该枚举类型的变量通过位逻辑取多个值。 这就是为什么建议每个枚举成员都使用2或0的幂的数字值的原因。
但是,C#不会阻止您定义一个值为3的成员。
这就提出了一个问题-C#如何组合具有数字值不为0或2的幂的成员的标志?
例如,一个普通的标志枚举将产生类似的东西(取自上面的MSDN链接):
// Define an Enum with FlagsAttribute.
[Flags]
enum MultiHue : short
{
None = 0,
Black = 1,
Red = 2,
Green = 4,
Blue = 8
};
static void Main( )
{
// Display all combinations of values, and invalid values.
Console.WriteLine("\nAll possible combinations of values with FlagsAttribute:");
for( int val = 0; val <= 16; val++ )
Console.WriteLine( "{0,3} - {1:G}", val, (MultiHue)val);
}
// All possible combinations of values with FlagsAttribute:
// 0 - None
// 1 - Black
// 2 - Red
// 3 - Black, Red
// 4 - Green
// 5 - Black, Green
// 6 - Red, Green
// 7 - Black, Red, Green
// 8 - Blue
// 9 - Black, Blue
// 10 - Red, Blue
// 11 - Black, Red, Blue
// 12 - Green, Blue
// 13 - Black, Green, Blue
// 14 - Red, Green, Blue
// 15 - Black, Red, Green, Blue
// 16 - 16
但是,如果我要向数字“ 3”的“ MultiHue”枚举中添加另一个成员,则会生成:
// Define an Enum with FlagsAttribute.
[Flags]
enum MultiHue : short
{
None = 0,
Black = 1,
Red = 2,
Lime = 3,
Green = 4,
Blue = 8
};
static void Main( )
{
// Display all combinations of values, and invalid values.
Console.WriteLine("\nAll possible combinations of values with FlagsAttribute:");
for( int val = 0; val <= 16; val++ )
Console.WriteLine( "{0,3} - {1:G}", val, (MultiHue)val);
}
0 - None
1 - Black
2 - Red
3 - Lime
4 - Green
5 - Black, Green
6 - Red, Green
7 - Lime, Green
8 - Blue
9 - Black, Blue
10 - Red, Blue
11 - Lime, Blue
12 - Green, Blue
13 - Black, Green, Blue
14 - Red, Green, Blue
15 - Lime, Green, Blue
16 - 16
注意如何用不同的成员表示不同的组合,例如:
4是“绿色”,但是也可以是“石灰,黑色”
7是“石灰,绿色”,而不是先前的“黑色,红色,绿色”
等等
我知道这是一个不好的做法,但是我想知道编译器如何确定某个位组合使用哪种成员组合?
这并不是禁止或允许组合或按位运算符(无论是否带有Flags
属性都被允许),以表明按位表示合理并影响ToString()
工作方式。
考虑:
public enum Color
{
Black = 0,
Blue = 1,
Green = 2,
Red = 4
}
这将使我们能够有意义地谈论8种颜色,具体取决于是否设置了给定的蓝色,绿色或红色标志。
我们可以在枚举中定义这些组合:
public enum Color
{
Black = 0,
Blue = 1,
Green = 2,
Cyan = 3,
Red = 4,
Magenta = 5,
Yellow = 6,
White = 7
}
请注意,这里的功能是相同的: Color.Green | Color.Red
Color.Green | Color.Red
具有相同的值6
任一的方法,当然这将指示黄色。 区别在于我们是否给它提供了方便的Yellow
标签。
我的枚举和您的枚举之间的主要区别是,我的组合具有某种一般意义,因为绿色和红色的光混合会变成黄色,依此类推。 通常,我们只会发现仅命名1位值(1、2、4、8…)很有用,但是有时命名特定的通用组合对于使用枚举的编码器很有用。 一个真正的例子是DateTimeStyles
。 在该枚举中, AllowLeadingWhite
的值为1, AllowTrailingWhite
的值为2, AllowInnerWhite
的值为4, AllowWhiteSpaces
的值为7,这是指示设置所有这三个标志的简便方法。
如果以二进制形式编写,则可以看到。
1 - black - 00000001
2 - red - 00000010
3 - lime - 00000011
所以3不是石灰,应该是blackRed。 3是黑色和红色。 您不仅可以将2的幂设置为更易于使用的组合。 相反,您可以将其与black和red进行比较。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.