我遇到了这个问题:[Flags] Enum Attribute 在 C# 中是什么意思?
我一直想知道的一件事是,使用接受的答案的例子,如果我声明会发生什么:
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 3,
Blue = 4
}
该示例中的以下步骤会导致错误吗?如果没有,我怎样才能到达 MyColors.Red?
我遇到了这个问题:[Flags] Enum Attribute 在 C# 中是什么意思?
我一直想知道的一件事是,使用接受的答案的例子,如果我声明会发生什么:
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 3,
Blue = 4
}
该示例中的以下步骤会导致错误吗?如果没有,我怎样才能到达 MyColors.Red?
Flags 属性实际上不会对枚举本身做任何事情,也不会影响它在代码中的使用方式。Flags 属性确实影响的唯一一件事是 ToString 方法的输出。Flags 属性的另一个目的是向开发人员指示他们应该如何使用枚举。您的示例不会导致任何错误;这只是愚蠢的代码。规则非常简单:
要详细说明 jdphenix 的答案,请记住该[Flags]
属性实际上并没有任何魔力。它只是在枚举上添加了一个纯粹的装饰标记,允许其他函数(默认情况下,只有枚举的ToString
实现)将枚举视为标志枚举。
不管属性如何,枚举仍然只是一个数字,默认情况下是 Int32,周围有一些语法糖。因此,如果您像以前那样定义枚举,则执行
MyColors newColor = MyColors.Yellow | MyColors.Green
只会对 1 和 2 进行按位或运算。按位枚举的魔力不在属性中,但事实上 2 的幂允许您“打开”和关闭某个位。使用序数将关闭作为多个枚举值的二进制表示的一部分的位,从而使按位运算的结果毫无意义。
这将导致意想不到的结果。实现唯一性的常见做法是用 2 的幂来标记枚举值。
例如Yellow
按位或Green
将导致Red
等。
MyColors colors = MyColors.Yellow | MyColors.Green;
if (colors == MyColors.Red)
{
Console.WriteLine("Oops!")
}
还要注意Flags
属性在这里什么都不做,它给人的印象是你可以使用按位或。
它不会按预期运行。对于每个枚举常量的声明值,您必须使用 2 的幂。这是直接来自您链接的答案的示例:
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}
如果声明的值为 2 的幂:
[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;