带有Flags属性的C#枚举

时间:2009-11-24 19:39:41

标签: c# attributes enums flags

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

例如。

[Flags]
public enum MyColor
{
    Yellow = 1,
    Green = 2,
    Red = 4,
    Blue = 8
}

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

4 个答案:

答案 0 :(得分:13)

这更容易

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

答案 1 :(得分:3)

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

答案 2 :(得分:3)

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

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

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

答案 3 :(得分:2)

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

[Flags]
public enum MyColor
{
    Yellow,
    Green,
    Red,
    Blue
 }

public class SomeClass
{
  public MyColor SomeColor;  // Yellow or undefined by default?
}

当一个类被实例化时,它的所有字段通常都被清零(引用变为空,值变为零)。但是如果第一个值是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?
}

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