带有标志属性的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? }
可能最好明确拼写出来以避免大规模混乱! 🙂