我想知道具有标志属性的枚举是否主要用于按位操作,如果枚举值未定义,编译器为什么不自动生成值。
例如。
[旗帜] 公共枚举 MyColor { 黄色 = 1, 绿色 = 2, 红色 = 4, 蓝色 = 8 }
如果未分配值 1、2、4、8 会自动生成,这将很有帮助。想知道你对此的看法。
我想知道具有标志属性的枚举是否主要用于按位操作,如果枚举值未定义,编译器为什么不自动生成值。
例如。
[旗帜] 公共枚举 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?
}
当一个类被实例化时,它的所有字段通常都被清零(引用变为空,值变为零)。但是如果第一个值是一个,那么编译器将不得不以不同于其他任何方式处理标志枚举。
因此,考虑到这一点,以及能够将位域归零这一事实非常有用,我们得出的结论是,第一个域在逻辑上实际上应该为零:
[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?
}
可能更好地明确说明以避免大量混淆!:-)