如果我们按顺序声明 [Flags] 枚举会发生什么

本文关键字:枚举 什么 Flags 我们 顺序 声明 如果 | 更新日期: 2023-09-27 17:55:26

我遇到了这个问题:[标志]枚举属性在C#中是什么意思?

我一直

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

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

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

如果我们按顺序声明 [Flags] 枚举会发生什么

Flags 属性实际上不会对自身进行枚举或影响它在代码中的使用方式执行任何操作。 Flags 属性唯一影响的事情是 ToString 方法的输出。 Flags 属性的另一个用途是向开发人员指示他们应如何使用枚举。 您的示例不会引起任何错误;这只是愚蠢的代码。 规则非常简单:

  1. 如果一次只应使用一个值,则不要应用 Flags 属性,而是为类型使用单数名称。
  2. 如果多个值可以一起使用,则应用 Flags 属性,对值使用 2 的幂,并对类型使用复数名称。

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

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

MyColors newColor = MyColors.Yellow | MyColors.Green 

只会对 1 和 2 进行按位 OR 运算。按位枚举的魔力不在于属性,而在于 2 的幂允许您"切换"某个位打开和关闭。使用序号将关闭属于多个枚举值的二进制表示形式的位,从而使按位运算的结果毫无意义。

这将导致意外的结果。使唯一性的常见做法是仅用 2 的幂标记枚举值。

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

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

另请注意Flags属性在此处不执行任何操作,它给人的印象是您可以使用按位 OR

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

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

如果声明的值不是 2 的幂:

  • 您将无法执行有意义的按位运算。
  • 您将能够将其用于普通枚举(不会有编译器错误)。

[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;