带有标志属性的C#枚举

我想知道带有Flag属性的枚举是否主要用于按位运算,如果枚举值未定义,编译器为什么不自动生成值。

例如。

 [标志]
 public enum MyColor
 {
    黄色= 1,
    绿色= 2,
    红= 4,
    蓝= 8
 }

如果未分配值1,2,4,8是自动生成的,那将会很有帮助。 想知道你对此的看法。

有点容易:

[Flags] public enum MyColor { Yellow = 1<<0, Green = 1<<1, Red = 1<<2, Blue = 1<<3 } 

他们可能会,但是对于这样大小的编译器,他们必须考虑实现某些东西所需的时间和资源与潜在的好处,特别是像这样的语法糖。 它只是语法糖,因为你可以手动编写它。

我希望这是因为FlagsAttribute实例是在Enum旁边或之后编译的。 也就是说使用属性(如[Flags])装饰对象会导致创建属性对象,但它不会以基本方式修改基础对象。

此外,存储的部分信息(用于属性的运行时实例化)是它所引用的实体。 实体枚举可能必须在其属性之前进行编译,因此属性不会影响它引用的实体(在本例中为枚举)。 我不知道这句话是真的,这只是猜测。

最重要的是属性,如[Flags],实际上是实体本身,而不是修饰的装饰类型。

我认为,除其他外,它将归结为对第一个价值的巨大混淆。 考虑:

 [Flags] public enum MyColor { Yellow, Green, Red, Blue } public class SomeClass { public MyColor SomeColor; // Yellow or undefined by default? } 

当一个类被实例化时,它的所有字段通常都被清零(引用变为null,值变为零)。 但是如果第一个值是1,那么编译器必须以不同于其他任何方式处理Flag枚举。

因此,考虑到这一点,以及能够将位域清零是非常有用的事实,我们得出的结论是第一个字段实际上应该逻辑上为零:

 [Flags] public enum MyColor { Black, //0 Yellow, //1 Green, //2 Red, //3 Blue //4 } 

但我想没有多少人会意识到这一点(没有上面的评论)。 还会出现更棘手的东西:

 [Flags] public enum MyColor { Black, Red, Green, Blue, Magenta = Red | Blue, Yellow = Red | Green | Blue, SomeOtherColor // now what would the value of this automatically be? } 

可能最好明确拼写出来以避免大规模混乱! 🙂