编辑:似乎大多数人误解了我的问题.
我知道枚举是如何运作的,我知道二进制.我想知道为什么带有[Flags]属性的枚举是按原样设计的.
原帖:
这可能是重复的,但我没有找到任何其他帖子,所以这里.
我打赌它背后有一些很好的理由,我发现它有点容易出错.
[Flag]
public enum Flagged
{
One, // 0
Two, // 1
Three, // 2
Four, // 3
}
Flagged f; // Defaults to Flagged.One = 0
f = Flagged.Four;
(f & Flagged.One) != 0; // Sure.. One defaults to 0
(f & Flagged.Two) != 0; // 3 & 1 == 1
(f & Flagged.Three) != 0; // 3 & 2 == 2
Run Code Online (Sandbox Code Playgroud)
如果做到这样的话会不会更有意义?
[Flag]
public enum Flagged
{
One = 1 << 0, // 1
Two = 1 << 1, // 2
Three = 1 << 2, // 4
Four = 1 << 3, // 8
}
Flagged f; // Defaults to 0
f = Flagged.Four;
(f & Flagged.One) != 0; // 8 & 1 == 0
(f & Flagged.Two) != 0; // 8 & 2 == 0
(f & Flagged.Three) != 0; // 8 & 4 == 0
(f & Flagged.Four) != 0; // 8 & 8 == 8
Run Code Online (Sandbox Code Playgroud)
当然..我不太确定它应该如何处理这样的自定义标志
[Flag]
public enum Flagged
{
One, // 1
Two, // 2
LessThanThree = One | Two,
Three, // 4? start from Two?
LessThanFour = Three | LessThanThree,
Three, // 8? start from Three?
}
Run Code Online (Sandbox Code Playgroud)
该规范提供了一些指导
定义2的幂的枚举常量,即1,2,4,8等.这意味着组合枚举常量中的各个标志不重叠.
但这应该是自动完成的,因为我打赌你永远不会想要我的第一个例子.请赐教:)
除非明确给出其他值,否则枚举的第一项为零.通常最佳做法是为标志枚举设置零值,因为它为零值提供了语义含义,例如"无标志"或"关闭".这有助于维护代码,因为它可能意味着代码的意图(尽管注释也实现了这一点).
除此之外,您和您的设计是否取决于您是否需要零值.
由于标志枚举仍然只是枚举(FlagsAttribute仅指示调试器将值解释为其他值的组合),因此枚举中的下一个值总是比前一个值多一个.因此,您应明确指定位值,因为您可能希望将组合表示为其他值的按位或.
也就是说,想象一个标志枚举的语法,要求所有按位组合放在枚举定义的末尾或以某种方式标记,这样编译器就知道如何处理其他所有内容,这并不是不合理的.
例如(假设一个flags关键字,我们在北半球),
flags enum MyFlags
{
January,
February,
March,
April,
May,
June,
July,
August,
September,
October,
November,
December,
Winter = January | February | March
Spring = April | May | June
Summer = July | August | September
Autumn = October | November | December
}
Run Code Online (Sandbox Code Playgroud)
使用此语法,编译器可以自己创建0值,并自动为其他值分配标志.