10

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

例如。

[旗帜]
公共枚举 MyColor
{
    黄色 = 1,
    绿色 = 2,
    红色 = 4,
    蓝色 = 8
}

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

4

4 回答 4

13

有点容易:

[Flags]
public enum MyColor
{
    Yellow = 1<<0,
    Green = 1<<1,
    Red = 1<<2,
    Blue = 1<<3
}
于 2009-11-24T19:44:41.330 回答
3

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

于 2009-11-24T19:42:54.827 回答
3

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

此外,存储的部分信息(用于属性的运行时实例化)是它所引用的实体。可能实体枚举必须在其属性之前编译,因此属性不能影响它所引用的实体(在这种情况下是枚举)。我不知道这个说法是否属实,这只是一个猜测。

最大的收获是属性,如 [Flags],实际上是实体本身,而不是修饰类型的修改。

于 2009-11-24T20:38:44.747 回答
2

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

[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?
}

可能更好地明确说明以避免大量混淆!:-)

于 2013-11-04T14:24:51.657 回答