码迷,mamicode.com
首页 > 其他好文 > 详细

第15章 枚举类型和位标志

时间:2016-06-26 19:39:34      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

Enumeration提供了一些非常炫酷的功能,相信大多数开发人员都不熟悉。这些新功能极大的简化了应用程序开发。

15.1枚举类型

枚举类型(enumerated types)定义了一组“符号名称/值”配对。

以下Color类型定义了一组符号,每个符号都标识一种颜色:

    internal enum Color

    {

        White,//赋值0

        Red,  //赋值1

        Greed,//赋值2

        Blue, //赋值3

        Orange//赋值4

}

当然,也可以写个程序用0代表白色,1代表红色,以此类推。但不应该将这些数字硬编码到代码中,而应换用枚举类型,因为:

  • 枚举类型使程序更容易编写、阅读和维护。
  • 枚举类型是强类型的。

每个枚举类型都直接从System.Enum派生,后者从System.ValueType派生。而System.ValueType又从System.Object派生。所以,枚举类型是值类型,可表示成未装箱和已装箱形式。有别于其他值类型,枚举类型不能定义任何方法、属性和事件。

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

 技术分享

C#编译器实际上并不编译这段代码,因为它禁止定义从System.Enum这一特殊类型派生的类型。

枚举类型定义的符号是常量值,所以当编译器一旦发现代码引用了一个枚举类型的符号,就会在编译时用数值替代符号,代码将不再引用定义了符号的枚举类型。

简单地说,枚举类型只是一个结构,其中定义了一组常量字段和一个实例字段。常量字段会嵌入程序集的元数据中,并可通过反射来访问。这意味着在运行时获得与一个枚举类型关联的所有符号及其值。还意味着可以将一个字符串符号转换成对应的数值。这些操作是通过System.Enum基类型来提供的。下面讨论其中的一些操作:

例如,System.Enum类型有一个名为GetUnderlyingType的静态方法,而System.Type类型有一个GetEnumUnderlyingType的实例方法。

public static Type GetUnderlyingType(Type enumType);

public virtual Type GetEnumUnderlyingType();

这些方法返回用于容纳一个枚举类型的值的基础类型。每个枚举类型都有一个基础类型,可以是byte,short,int(最常用,也是C#默认选择的),long。C#要求只能指定基元类型名称,如果使用FCL类型名称(比如Int32),会报错。

我们定义的枚举类型应该与需要调用它的那个类型同级。

 

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

 

    internal enum Color : byte

    {

        White,

        Red,

        Greed,

        Blue,

        Orange

}

static void Main()

        {

            Console.WriteLine(Enum.GetUnderlyingType(typeof(Color))); //System.Byte

    }

C# typeof() 和 GetType()区是什么?

  • typeof(x)中的x,必须是具体的类名、类型名称等,不可以是变量名称。
  • GetType()方法继承自Object,所以C#中任何对象都具有GetType()方法,它的作用和typeof()相同,返回Type类型的当前对象的类型。

C#编译器将枚举类型视为基元类型,所以,可以用许多熟悉的操作符(==,!=,<,>,<=,>=,+,-,^,&,|,++,--)来操纵枚举类型的实例。

所有这些操作符实际作用于每个枚举类型实例内部的value_实例字段。

给定一个枚举类型的实例,可调用从System.Enum继承的ToString方法:

    public static class Program

    {

        static void Main()

        {

            //Console.WriteLine(Enum.GetUnderlyingType(typeof(Color)));

            Color c = Color.Blue;

            Console.WriteLine(c.ToString());//"Blue" 常规格式

            Console.WriteLine(c.ToString("G"));//"Blue" 常规格式

            Console.WriteLine(c.ToString("D"));//"3" 十进制格式

            Console.WriteLine(c.ToString("X"));//"03" 十六进制格式

        }

 

    }

 

    internal enum Color : byte

    {

        White,

        Red,

        Greed,

        Blue,

        Orange

    }

 技术分享

Format可调用它格式化一个枚举类型的值:

public static string Format(Type enumType, object value, string format);

Console.WriteLine(Enum.Format(typeof(Color), 3, "G"));//显示"Blue"

GetValues:获取枚举类型中定义的所有符号以及对应的值。

public static Array GetValues(Type enumType);

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

            Console.WriteLine("Number of symbols defined:" + colors.Length);

            Console.WriteLine("Value\tSymbol\n-----\t------");

            foreach (Color c in colors)

            {

                Console.WriteLine("{0,5:D}\t{0:G}", c);

            }

GetName:返回数值的字符串表示。

Enum.GetName(typeof(Color), 3);//"Blue"

GetNames:返回一个String数组,每个符号都代表一个String。

Enum.GetNames(typeof(Color));

    //        {string[5]}

    //[0]: "White"

    //[1]: "Red"

    //[2]: "Greed"

    //[3]: "Blue"

    //[4]: "Orange"

Parse, TryParse:将一个符号转换成枚举类型的实例。

public static object Parse(Type enumType, string value, bool ignoreCase);

 

Color c = (Color)Enum.Parse(typeof(Color), "orange", true); //Orange

Enum.Parse(typeof(Color), "0", true);//White

bool a=Enum.TryParse<Color>("Brown", false, out c);//false, 枚举中没有定义Brown

IsDefine:判断一个值对于一个枚举类型是否合法。

Enum.IsDefined(typeof(Color), "white");//false, 执行的是区分大小写的检查

Enum.IsDefined(typeof(Color), 5);//false, Color枚举类型没有与5对应的符号

15.2位标志

我们可以将位标志当做一种特殊的枚举类型。

FileAttributes类型是基本类型为Int32的枚举类型,其中每一位都反映文件的一项属性。

 [Flags] //指示可以将枚举作为位域(即一组标志)处理。

    public enum FileAttributes

    {

        ReadOnly = 1,

        Hidden = 2,

        System = 4,

        Directory = 16,

        Archive = 32,

        Device = 64,

        Normal = 128,

        Temporary = 256,

        SparseFile = 512,

        ReparsePoint = 1024,

        Compressed = 2048,

        Offline = 4096,

        NotContentIndexed = 8192,

        Encrypted = 16384,

        IntegrityStream = 32768,

        NoScrubData = 131072

    }

以上FileAttributes类型中,1的二进制为1,2的二进制为10,4的二进制为100。也就是说可以用每个二进制位来确认唯一性,这就是位标志的原理。

public static void Main()

        {

 

            //得到可执行文件(.exe文件)的相对路径(如:"...\bin\Debug\ConsoleApplication1.exe")

            String file = Assembly.GetEntryAssembly().Location;

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

            FileAttributes attributes = File.GetAttributes(file);

            //因为二进制1&1才为1,所以只要存在最后的数值一定不为1,判断文件是否隐藏

            Console.WriteLine("IS {0} hidden?{1}", file, (attributes & FileAttributes.Hidden) != 0);

            //判断文件是否隐藏,换种写法。Enum有一个HasFlag方法,确定当前实例attributes中是否设置了一个或多个位域

            Console.WriteLine("IS {0} hidden?{1}", file, attributes.HasFlag(FileAttributes.Hidden));

            //将一个文件的属性改为只读和隐藏

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

        }

第15章 枚举类型和位标志

标签:

原文地址:http://www.cnblogs.com/chrisghb8812/p/5618303.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!