5

我遇到了这个问题:[Flags] Enum Attribute 在 C# 中是什么意思?

我一直想知道的一件事是,使用接受的答案的例子,如果我声明会发生什么:

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

该示例中的以下步骤会导致错误吗?如果没有,我怎样才能到达 MyColors.Red?

4

5 回答 5

9

Flags 属性实际上不会对枚举本身做任何事情,也不会影响它在代码中的使用方式。Flags 属性确实影响的唯一一件事是 ToString 方法的输出。Flags 属性的另一个目的是向开发人员指示他们应该如何使用枚举。您的示例不会导致任何错误;这只是愚蠢的代码。规则非常简单:

  1. 如果一次只应该使用一个值,则不要应用 Flags 属性并为该类型使用单数名称。
  2. 如果多个值可以一起使用,则应用 Flags 属性,对值使用 2 的幂,并为类型使用复数名称。
于 2014-03-31T06:54:32.757 回答
3

要详细说明 jdphenix 的答案,请记住该[Flags]属性实际上并没有任何魔力。它只是在枚举上添加了一个纯粹的装饰标记,允许其他函数(默认情况下,只有枚举的ToString实现)将枚举视为标志枚举。

不管属性如何,枚举仍然只是一个数字,默认情况下是 Int32,周围有一些语法糖。因此,如果您像以前那样定义枚举,则执行

MyColors newColor = MyColors.Yellow | MyColors.Green 

只会对 1 和 2 进行按位或运算。按位枚举的魔力不在属性中,但事实上 2 的幂允许您“打开”和关闭某个位。使用序数将关闭作为多个枚举值的二进制表示的一部分的位,从而使按位运算的结果毫无意义。

于 2014-03-31T06:56:27.720 回答
1

这将导致意想不到的结果。实现唯一性的常见做法是用 2 的幂来标记枚举值。

例如Yellow按位或Green将导致Red等。

MyColors colors = MyColors.Yellow | MyColors.Green;
if (colors == MyColors.Red)
{
    Console.WriteLine("Oops!")
}

还要注意Flags属性在这里什么都不做,它给人的印象是你可以使用按位或

于 2014-03-31T06:59:28.223 回答
1

它不会按预期运行。对于每个枚举常量的声明值,您必须使用 2 的幂。这是直接来自您链接的答案的示例:

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

如果声明的值为 2 的幂:

  • 您将无法执行有意义的按位运算。
  • 您将能够将其用于普通枚举(不会出现编译器错误)。
于 2014-03-31T06:52:50.220 回答
1

[Flags] 属性所做的只是允许您将按位运算符应用于枚举。

[编辑是正确的 - 如果你不指定 [Flags] 甚至没有警告 - 我可以发誓它曾经是这样的......]

您拥有的 =3 (红色)非常有用,因为您可以定义组合来检查...在您的示例中:

[Flags]
public enum MyColors
{
    Yellow = 1,
    Green = 2,
    YellowAndGreen = 3,
    Blue = 4
}

现在,显然这是一个愚蠢的例子,但请考虑以下内容:

[Flags]
public enum MyStuff
{
    HasCar = 1,
    HasDog = 2,
    HasKids = 4,
    HasEverything = 7,
}

现在,要检查变量是否包含所有内容,您可以执行以下操作:

return (myStuff & MyStuff.HasEverything) == MyStuff.HasEverything;
于 2014-03-31T06:55:46.713 回答