枚举类型
枚举类型是一种特殊的值类型,可以在枚举类型中定义一组命名的数值常量:
public enum BorderSide { Left, Right, Top, Bottom }
使用枚举类型的方法如下:
BorderSide topSide = BorderSide.Top;
bool isTop = (topSide == BorderSide.Top); // true
🍁 枚举类型的底层原理 🍁
-
每个枚举成员都对应一个底层整型数值(
Enum.GetUnderlyingType()
)。在默认情况下:- 对应的数值是
int
类型的。 - 按照枚举成员的声明顺序,自动按照 0、1、2 …… 进行常量赋值。
- 对应的数值是
-
可以指定其他的整数类型代替默认类型:
public enum BorderSide : byte { Left, Right, Top, Bottom }
-
也可以显式指定每一个枚举成员对应的值:
public enum BorderSide : byte { Left = 1, Right = 2, Top = 10, Bottom=11 }
-
编译器还支持显示指定部分枚举成员,没有指定的枚举成员,在最后一个显示指定的值基础上递增:
public enum BorderSide : byte { Left = 1, Right, Top = 10, Bottom }
1 枚举类型转换
枚举类型的实例可以与它对应的整数值相互转换:
int i = (int)BorderSide.Left;
BorderSide side = (BorderSide)i;
也可以显式将一个枚举类型转换为另一个。假设 HorizontalAlignment
定义为:
public enum HorizontalAlignment
{
Left = BorderSide.Left,
Right = BorderSide.Right,
Center
}
则两个枚举类型之间的转换时通过对用的数值进行的:
HorizontalAlignment h = (HorizontalAlignment)BorderSide.Right;
// same as:
HorizontalAlignment h = (HorizontalAlignment)(int)BorderSide.Right;
在枚举表达式中,编译器会特殊对待数值 0,它不需要进行显式转换:
BorderSide b = 0; // No cast required
if (b == 0) ...
对 0 进行特殊对待的原因有两个:
- 第一个枚举经常作为默认值。
- 在合并枚举类型中,0 表示无标志。
2 标志枚举类型 Flags Enums
枚举类型的成员可以合并。为了避免混淆,合并枚举类型的成员要显式指定值,典型的值为 2 的幂次:
[Flags]
public enum BorderSides
{
None = 0,
Left = 1,
Right = 2,
Top = 4,
Bottom = 8
}
-
可以使用位运算符合并枚举类型的值,例如:
|
和&
:BorderSides leftRight = BorderSides.Left | BorderSides.Right; if ((leftRight & BorderSides.Left) != 0) Console.WriteLine ("Includes Left"); // Includes Left string formatted = leftRight.ToString(); // "Left, Right" BorderSides s = BorderSides.Left; s |= BorderSides.Right; Console.WriteLine (s == leftRight); // True s ^= BorderSides.Right; // Toggles BorderSides.Right Console.WriteLine (s); // Left
-
按照惯例,当枚举类型成员可以合并时,其枚举类型一定要应用
Flags
特性。如果声明了一个没有标注Flags
特性的枚举类型,其成员依然可以合并,但若调用ToString
方法,则会输出一个数值而非一组名字。 -
一般来说,合并枚举类型通常用复数名词而不用但单数形式。
-
可以将合并的成员直接放在枚举的声明内:
[Flags] public enum BorderSides { None = 0, Left = 1, Right = 2, Top = 4, Bottom = 8, LeftRight = Left | Right, TopBottom = Top | Bottom, All = LeftRight | TopBottom }
3 枚举运算符
枚举类型可用的运算符有:
= == != < > <= >= + - ^ & | ˜
+= -= ++ -- sizeof
- 位运算符、算术运算符和比较运算符都是返回对应整数值的运算结果
- 枚举类型和整数类型之间可以做加法,但两个枚举类型之间不能做加法
4 类型安全问题
以下枚举类型:
public enum BorderSide { Left, Right, Top, Bottom }
-
枚举类型的真实值可能超出枚举类型成员的数值范围:
BorderSide b = (BorderSide) 12345; Console.WriteLine (b); // 12345
-
位运算符和算术运算符也可能产生类似的非法值:
BorderSide b = BorderSide.Bottom; b++; // No errors
-
通过使用静态方法 Enum.IsDefined 来显式检查枚举值的合法性(支持 Flag Enums):
BorderSide side = (BorderSide) 12345; Console.WriteLine (Enum.IsDefined (typeof (BorderSide), side)); // False // 或者直接对 12345判断 Console.WriteLine (Enum.IsDefined (typeof (BorderSide), 12345)); // False