枚举类型和位标志

一、枚举类型

1,编译枚举时,C#编译器把每个符号转换成类型的一个常量字段。例如将Color枚举类型看成以下代码

    //编译枚举时,c#编译器把每个符号转化成类型的一个常量字段
    internal struct Color : System.Enum
    {
        //以下一些公共常量,它们定义了Color的符号和值
        public const Color White = (Color) 0;
        public const Color Red = (Color) 1;
        //以下是一个公共实例字段,包含Color变量的值
        //不能写代码来直接引用该字段
        public Int32 value_;
    }

简单的说,枚举是一个结构,其中定义了一组常量字段和一个实例字段。常量字段会嵌入程序集的元数据中,并可以通过反射来访问

2,以下代码显示了如何声明一个基础类型为byte的枚举类型:

    internal enum Color : byte
    {
        Red
    }

3,枚举的使用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            //返回用于容纳一个枚举类型的基础类型
            //System.Int32
            Console.WriteLine(Enum.GetUnderlyingType(typeof (ConsoleColor)));

            //输出枚举
            Console.WriteLine(ConsoleColor.Blue);//Blue(常规格式)
            Console.WriteLine(ConsoleColor.Blue.ToString());//Blue(常规格式)
            Console.WriteLine(ConsoleColor.Blue.ToString("G"));//Blue(常规格式)
            Console.WriteLine(ConsoleColor.Blue.ToString("D"));//9(十进制格式)
            Console.WriteLine(ConsoleColor.Blue.ToString("X"));//00000009(十六进制格式)


            //获取枚举数组
            var s = (ConsoleColor[]) Enum.GetValues(typeof (ConsoleColor));
            foreach (var consoleColor in s)
            {
                Console.WriteLine("{0,5:D}	{0:G}",consoleColor);
            }

            //输出Blue
            Console.WriteLine(Enum.GetName(typeof (ConsoleColor), 9)) ;

            //根据名称获取枚举值,没找到则抛异常
            var color = (ConsoleColor) Enum.Parse(typeof (ConsoleColor), "Blue", true);

            //根据枚举值获取枚举
            ConsoleColor c;
            Enum.TryParse<ConsoleColor>("9", true, out c);
            Console.WriteLine(c.ToString()); //输出Blue
            Enum.TryParse<ConsoleColor>("1231", true, out c);
            Console.WriteLine(c.ToString());//输出1231

            //IsDefined方法判断数据对于某枚举是否合法
            Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor),1));//True 存在该值的枚举
            Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor), "Blue"));//True 存在该名称的枚举
            Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor), "blue"));//Flase 不存在该名称的枚举(区分大小写)
            Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor), 1231));//Flase 不存在该值的枚举
            Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor), (ConsoleColor)1231));//Flase 不存在该值的枚举

            Console.ReadKey();
        }
    }
}

 IsDefined使用需谨慎,首先它总是执行区分大小写的查找;其次它相当慢,因为它在内部使用了反射

4,枚举的默认值

如果没有为枚举显示设置值得话,会有默认值

二、位标志

定义用于标识位标识的枚举类型时,当然应该显示为每个符号分配一个数值。强烈建议向枚举类型应用[Flags]特性

    [Flags]
    public enum Status
    {
        Start=1,
        Order=2,
        End=4,
        All= Start| Order
    }

1,[Flags]特性

//Status s = (Status)5;
Status s = Status.Start | Status.End;//5 Console.WriteLine(s.ToString());//Start,End
Console.WriteLine(s.ToString("F"));//如果不加上flags特性可以使用“F”格式获得正确的字符串

调用ToString时,他会视图将数值转换为对应的符号。现在的数值是5,没有对应的符号。如果不加上[Flags]特性的话,就会显示5。加上该特性,就会把它视为一组为标志,由于5是由1(Start)和4(End)组成,所以ToString会生成字符串Start,End

2,位标志的使用

            //由于Start被定义为1,所以"s"被初始化为1
            Status s =(Status)Enum.Parse(typeof (Status), "Start", true);
            Console.WriteLine(s.ToString());//Start

            //由于Start和End已定义,所以"s1"初始化为5
            Status s1;
            Enum.TryParse<Status>("Start,End", true, out s1);
            Console.WriteLine(s1.ToString());//Start,End

            //创建一个Status枚举实例,其值为7
            Status s2 = (Status)Enum.Parse(typeof(Status),"7", true);
            Console.WriteLine(s2.ToString());//All,End
学习永不止境,技术成就梦想。
原文地址:https://www.cnblogs.com/zd1994/p/6914413.html