什么是枚举
枚举是一个特殊的值类型,他可以让你指定一组命名的数值常量
public enum
BorderSide { Left,Right,Top,Bottom }
BorderSide topSide =BorderSide.Top;
bool isTop = (topSide==BorderSide.Top); //true
枚举的底层原理
每个枚举都对应一个底层的整形数值(Enum.GetUnderlyingType()).默认:是int类型
0,1,2..会按照枚举成员的声明顺序自动赋值
也可以指定其他的类型作为枚举的整数类型,例如byte:
public enum BoderSide : byte { left,Right,Top,Bottom }
也可以单独指定枚举成员对应的整数值
public enum BorderSide : byte { Left=1,Right=2,Top=10,Bottom=12 }
也可以只指定其中某些成员的数值,未被赋值的成员将接着它前面已赋值的成员的值进行递增
枚举的转换
枚举可以显式的和其底层的数值进行相互转换(和枚举代表的值)
int i = (int)Border.Top;
Border side = (Border)i;
bool leftOrRight = (int)side <= 2;
0
在枚举表达式里面,0数值会被编译器特殊对待,它不需要显式的转换:
BorderSide b = 0;
if(b == 0) ...
因为枚举的第一个成员通常被当做“默认值”,它的值默认就是0
组合枚举里,0表示没有标志(flags)
FLAGS ENUM
可以对枚举的成员进行组合
为了避免歧义,枚举成员需要显示的赋值。典型的就是使用2的乘幂
[Flags]
public enum BorderSides { None=0,Left=1,Right=2,Top=4,Bottom=8 }
flags enum,可以使用位操作符,例如|和&
[Flags] //(使用了Flags属性)
public enum BorderSides
{
None = 0, Left = 1, Right = 2, Top = 4, Bottom = 8
}
BorderSides leftRight = BorderSides.Top | BorderSides.Right;
if ((leftRight & BorderSides.Left) != 0)
System.Console.WriteLine("Includes Left");
string formatted = leftRight.ToString(); //使用[flags]"Left,Right",如果不使用[Flags]就是输出一个数值
BorderSides s = BorderSides.Left;
s |= BorderSides.Right;
Console.WriteLine(s == leftRight); //True
s ^= BorderSides.Right; //Roggles BorderSides.Right
Console.WriteLine(s); // Left
FLAGS ENUM底层原理
FLAGS属性
按约定,如果枚举成员可组合的话,flags属性就应该应用在枚举类型上。
如果生命了这样的枚举却没有使用flags属性,你仍然可以组合枚举的成员,但是调用枚举实例的ToString()方法是,输出的是一个数值而不是一组名称。
按约定,可组合枚举的名称应该是复数的。 英文加上s
在声明可组合枚举的时候,可以直接使用组合的枚举成员作为成员:
[Flags]
public enum BorderSider
{
None=0,
Left=1,Right=2,Top=4,Bottom=8,
LeftRight = Left|Right,
TopBottom = Top|Bottom,
All = LeftRight|TopBottom
}
枚举支持的操作符
类型安全的问题
public enum BorderSide{ Left,Right,Top,Bottom }
BorderSide b = (BorderSide) 12345;
Console.WirteLine(b); //12345
BorderSide b =BorderSide.Bottom;
b++; //No errors
检查枚举值的合理性:Enum.IsDefined()静态方法。
BorderSide side =(BorderSide)12345;
Console.WriteLine(Enum.IsDefined(typeof(BorderSide),side));//false
如果是false就说明枚举值是不合理的。什么是嵌套类型
嵌套类型就是声明在另一个类型作用范围内的类型
public class TopLevel
{
public class Nested{}
public eunum Color{ Red,Blue,Tan}
}
嵌套类型的特性
可访问封闭类型的私有成员,以及任何封闭类型能访问的东西
可以使用所有访问修饰符来声明,不仅仅是public和internal
嵌套类型的默认访问级别是private而不是internal
从封闭类型外面访问嵌套类型需要使用到封闭类型的名称
嵌套类型的例子
思考题
public enum BorderSide { Left,Right,Top,Bottom }
如何把上面这个枚举类型变成一个含有其所有成员/底层数值的集合?
[BorderSide.Left,Border.Right,BorderSide.Top,BorderSide.Bottom]
[0,1,2,3]