zoukankan      html  css  js  c++  java
  • 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	Symbol
    -----	------");
    foreach (var c in colors)
        WriteLine($"{c:D}	{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 向枚举类型添加方法

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

  • 相关阅读:
    POJ2155 Matrix
    POJ3469 Dual Core CPU
    洛谷P1469找筷子
    CodeForces 97D. Robot in Basement
    UVa11542 Square
    清澄 A1485. Catch The Penguins 抓企鹅
    Bzoj2595: [Wc2008]游览计划
    HDU4085 Peach Blossom Spring
    CodeForces 333E. Summer Earnings
    洛谷P3389 【模板】高斯消元法
  • 原文地址:https://www.cnblogs.com/errornull/p/9982791.html
Copyright © 2011-2022 走看看