zoukankan      html  css  js  c++  java
  • CLR笔记:12.枚举类型和位标志

    12.1    枚举类型
    强类型,枚举之间进行不能隐式转换
    枚举类型直接派生于System.Enum,后者派生于System.ValueType,值类型,可以使用装箱/拆箱
    不能定义方法/属性/事件。

    同一个枚举中,多个枚举符号有相同的数值,数值转符号时,会返回其中第一个符号。
    枚举类型要与使用它的类在同一级。

    默认为int,可以指定枚举成员的类型,只有int,uint,byte,sbyte,long,ulong,short,ushort这8种基元类型。
    可以使用操作符作用于枚举类型,实际上是作用于相应的value实例字段,如++。
    可以将枚举类型的实例显示转型为另一个不同的枚举类型,其实是先转为值,再反过去在另一个枚举中根据值找对应枚举值。
    可以显示将枚举类型的实例转型为一个数值类型。
        public enum Color
        
    {
            Red,
            Black,
            White
        }


        
    public enum Sentence
        
    {
            hello,
            bye
        }


        
    class Program
        
    {
            
    static void Main(string[] args)
            
    {
                
    //使用运算符,++
                Color a = Color.Red;
                
    ++a;

                Sentence s;
                
    //两个不同的枚举相互转换, 但是发现Color.White值为2,相应在Sentence中找不到,所以直接返回整数2
                s = (Sentence)Color.White;    //等价于(Sentence)1;

                
    //两个不同的枚举相互转换,返回枚举值Black
                s = (Sentence)Color.Black;

                
    //直接输出White枚举值, 显式转为整数
                Console.WriteLine(Color.White);         //输出white
                Console.WriteLine((Int32)Color.White);  //输出2
            }

        }


    如 enum Color{Red=1, White=2}对应IL:

    可以看到,枚举只是一个在其中定义一系列常量字段和实例字段的结构。
    如果只使用Color.Red这样的类型,则会作为常量处理,从而代码不再引用定义了的枚举类型,可以删除相应的dll(具体见第7章);
    如果使用Color c = new Color();这样的语法,那么依赖于引用,不可以删除相应的dll

    枚举方法列表:

    1.GetUnderlyingType静态方法,获取枚举类型值的核心类型:

                //返回System.Int
                Enum.GetUnderlyingType(typeof(Color));

    2.ToString()方法

                Color c = Color.Black;

                Console.WriteLine(c);                   
    //输出Black
                Console.WriteLine(c.ToString());        //输出Black
                Console.WriteLine(c.ToString("G"));     //输出Black,以上都是泛型格式
                Console.WriteLine(c.ToString("D"));     //输出1,十进制
                Console.WriteLine(c.ToString("X"));     //输出00000001,十六进制

    对于c.ToString("X")十六进制格式,A-F始终是大写字母。此外,输出的数位个数取决于Color的基本类型:
        byte/sbyte      2位
        short/ushort    4位
        int/uint            8位
        long/ulong     16位

    3.Format静态方法,功能基本同ToString()方法,但允许value传递一个数值,而不仅仅是一个Enum类型

                Enum.Format(typeof(Color), 3"G");

    4.GetValues静态方法,返回一个数组,数组中为所有的枚举类型名称:

                Color[] colors = (Color[])Enum.GetValues(typeof(Color));

    5.static String GetName(Type enumType, Objbect value)静态方法,返回数值的字符串表示
    6.static String[] GetNames(Type enumType),返回方法5的数组表示
    7.Parse静态方法,将一个符号转换为枚举类型的一个实例:

                Color cc1 = (Color)Enum.Parse(typeof(Color), "2");
                Color cc2 
    = (Color)Enum.Parse(typeof(Color), "Black");         //可以是值,也可以是枚举类型名称
                Color cc3 = (Color)Enum.Parse(typeof(Color), "Black"true);   //可选参数true表示忽略大小写

    8.IsDefined静态方法,判断一个数值对于一个枚举类型是否合法:

                Enum.IsDefined(typeof(Color), 10);  //返回false,Color中没有10
                Enum.IsDefined(typeof(Color), "Black");  //返回true

    常用于参数验证:

            public void SetColor(Color c)
            
    {
                
    if (!Enum.IsDefined(typeof(Color), c))
                
    {
                    
    //抛出异常,c不适合Color
                }

            }

    注:Enum.IsDefined方法慎用,因为要区分大小写查找;使用反射机制,速度慢。

    9.ToObject静态方法,一系列方法,如Enum.ToObject (Type, Byte),将Int32,Byte等类型实例转为枚举类型的实例(由于返回都是Object,所以要显示转型)

    12.2    位标志 bit flag
    位标志是一个位集合,其中有些位on,有些位off;而枚举是一个数值,是位集合中若干值的累加。
    在枚举上应用[Flags]属性,就可以用枚举来表示一组可以组合的位标志,一般要定义一个值为0的None符号。

    [Flags]
    public enum FileAttributes
    {
        ReadOnly 
    = 0x0001,
        Hidden 
    = 0x0002,
        System 
    = 0x0004
    }

    这时,就可以使用位运算来操作:

    逻辑与,判断是否有这个枚举值
            //以下代码,先取出文件的属性列表——是一个位集合,
            
    //与FileAttributes.Hidden做逻辑:如果位集合中有FileAttributes.Hidden,则返回FileAttributes.Hidden
            String file = @"C:\Boot.ini";
            FileAttributes attributes 
    = File.GetAttributes(file);
            
    if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { }

    逻辑或,组合出所需的枚举列表,一般用来设置:

            File.SetAttributes(path, FileAttributes.ReadOnly | FileAttributes.Hidden);

    对位标记Enum调用ToString()方法,数值转字符串:
        先检查是否应用了[Flags]属性
            如果没有,就查找与该数值匹配的Enum符号并返回,没有匹配就返回数值。
            如果有,就获取Enum降序排列的数值集合A,将A中的数值“按位与”Enum实例中的数值,将结果等于数值的Enum项附加到输出字符串,以逗号分割,如"Read,Write"
            有两种特殊情况:
                1.一个数值不能由Enum的若干项组合,则返回该数值
                2.应该定义0。

    对位标记Enum调用Parse()方法,字符串转数值:

                Enum.Parse(typeof(Color), "Query");
                Enum.Parse(
    typeof(Color), "Query, Read");
                Enum.Parse(
    typeof(Color), "28");

        处理过程如下:
            1.删除字符串中所有空白字符
            2.如果字符串以+/-/数字开始,那么字符串被认为是一个数字,直接转型为对应数值的字符串
            3.以逗号分割字符串,在Enum中查找相应符号的数值,按位或取值并返回

    不要对位标记Enum调用IsDefined()方法,因为,
        传字符串,位标记中含有逗号,但永远找不到含有逗号的枚举符号;
        传数值,永远返回false

  • 相关阅读:
    “耐撕”团队 2016.03.25 站立会议
    [Java面试二]Java基础知识精华部分.
    [Java面试一]面试复习大纲.
    [Java面试四]Strust2总结及在面试中的一些问题.
    [Java面试五]Spring总结以及在面试中的一些问题.
    [Java面试六]SpringMVC总结以及在面试中的一些问题.
    [Java面试七]Mybatis总结以及在面试中的一些问题.
    Hibernate总结以及在面试中的一些问题.
    脚本语言知识总结.
    浏览器跨域问题.
  • 原文地址:https://www.cnblogs.com/Jax/p/906852.html
Copyright © 2011-2022 走看看