CLR via C#学习笔记-第十五章-枚举类型

15.1 枚举类型

枚举类型定义了一组"符号名称/值"配对。

例如以下Color类型定义了一组符号,每个符号都表示一种颜色:

internal enum Color{
    White,//赋值0
    Red,//赋值1
    Green,//赋值2
    Blue//赋值3
}

使用枚举的好处

①枚举类型是程序更容易编写、阅读和维护。

②枚举是强类型的

枚举的特性

枚举类型在类型系统中是一等公民。每个枚举类型都从System.Enum派生,后者从System.ValueType派生,而System.ValueType又从System.Object派生,所以枚举类型是值类型。

可以未装箱和已装箱的形式来表示。有别于其他值类型,枚举不能定义任何方法、属性、事件。不过可以利用扩展方法模拟向枚举类型添加方法。

枚举的实质

编译枚举时编译器把每个符号转换成类型的一个常量字段,编译器将前面的Color枚举类型看成是以下代码:

internal struct Color:System.Enum{
    public const Color White = (Color) 0;
    public const Color Red   = (Color) 1;
    public const Color Green = (Color) 2;
    public const Color Blue  = (Color) 3;
    public Int32 value_;
}

编译器不会实际编译上述代码,因为他禁止定义从特殊类型System.Enum派生的类型。

简单说,枚举类型只是一个结构,定义了一组常量字段和一个实例字段。

枚举的声明

枚举默认是int类型的,也可以声明为其他基础类型

internal enum Color:byte{
    White,
    Red,
    Green,
    Blue
}

使用GetUnderlyingType获取枚举类型使用的基础类型

Enum.GetUnderlyingType(typeof(Color));

编译器将枚举类型视为基元类型。可以使用许多操作符来操纵枚举类型的实例。

编译器允许将枚举类型实例显示转换为不同的枚举类型,也可显式将枚举类型实例转型为数值类型。

枚举的值的格式化

给定一个枚举类型的实例,可以调用ToString输出枚举的值或者对应的符号。

Color color = Color.Blue;
WriteLine(color);//Blue
WriteLine(color.ToString());//Blue
WriteLine(color.ToString("G"));//常规,Blue
WriteLine(color.ToString("D"));//十进制,3
WriteLine(color.ToString("X"));//十六进制,00000003

除了ToString还有Format方法用来格式化枚举类型的值

public static String Format(Type enum,Object value,String format);//format方法以及参数
Enum.Format(typeof(Color),3,"G");//Blue

Format的优势是允许为value传值,这样就不一定需要有枚举类型的实例。

获取枚举的成员输出在数组里

使用System.Enum的静态方法GetValues或者System.Type的实例方法GetEnumValues来返回一个数组,数组中的每个元素都对应枚举类型中的一个符号名称,每个元素都包含符号名称的数值。

public static Array GetValues(Type enumType);//System.Enum中定义
public Array GetEnumValues();//System.Type中定义

结合ToString方法使用以显示枚举类型中所有符号名称以及对应数值。

Color[] colors =(Color[])Enum.GetValues(typeof(Color));
WriteLine("Number of symbol defined:"+colors.Length);
WriteLine("Value\tSymbol\n-----\t------");
foreach (var c in colors)
    WriteLine($"{c:D}\t{c:G}");//十进制和常规格式显示每个符号
ReadKey();

以上代码输出如下:

Number of symbol defined:4
Value   Symbol
-----   ------
0       White
1       Red
2       Green
3       Blue

作者不喜欢有以上两种方法,因为二者均是返回一个Array需要转型成恰当的数组类型,作者选择用自己定义泛型GetEnumValues方法,这样可以获得更好的编译时类型安全性。,上例中的第一句代码可以简化成如下形式

Color[] colors=GetEnumValues<Color>();

根据成员的值获取枚举中对应的符号

除了GetValues方法,还提供了以下方法来返回枚举类型的符号:

//返回数值的字符串表示
public static String GetName(Type enumType,Object value);//Enum中定义
public String GetEnumName(Object value);//Type中定义
//返回一个String数组,枚举中每一个符号都对应一个String
public static String[] GetNames(Type enumType);//Enum中定义
public String[] GetEnumNames();//Type中定义

根据符号获取枚举值对应的值

还有查找与符号对应的值的方法:Parse、TryParse,以下代码演示了如何是通用这些方法:

Color c=(Color)Enum.Parse(typeof(Color),"blue",true);//c被初始化为3第三个参数是是否忽视大小写
Color c=(Color)Enum.Parse(typeof(Color),"brown",false);//不存在该符号,报错
Enum.TryParse<Color>("1",false,out c);//创建值为1的Color枚举类型实例

判断值对于某枚举是否合法

Enum的静态isDefined方法和Type的IsEnumDefined方法用于判断数值对于某枚举类型是否合法

public static bool IsDefined (Type enumType, object value);
public bool IsEnumDefined(Object value);

Enum提供了一组静态ToObject方法,可以将各种基元类型实例转换为枚举实例。

枚举与需要其的类同级

枚举通常需要与需要他的类同级,是为了减少代码的录入量。


15.2 位标志

调用System.IO.File类型的GetAttributes方法,返回FileAttributes类型的一个实例。

FileAttributes类型是基本类型为int的枚举类型,其中每一位都反应了文件的一个特性。


 

15.3 向枚举类型添加方法

现在可以利用扩展方法模拟向枚举类型添加方法。

posted @ 2018-11-19 14:01  田错  阅读(170)  评论(0编辑  收藏  举报