《CLR via C#》读书笔记(11) -- 枚举

自从开始系统学习CLR via C#以来,看到CLR的什么功能总想深入了解内部是如何实现的。研究枚举时也不例外。首先看一下枚举的庐山真面目:

定义一个如下的枚举:

public enum Colors:ushort
{
        Red,
        Blue,
        Green
}

注意:此处的:ushort并不是描述一个继承关系。它是用来描述该枚举所采用的基础类型为ushort. 让我们再来看一下编译器生成的代码:

image

其实经过编译器处理之后,这个枚举变成了一个继承自System.Enum的类。

  • 我们定义的每一个枚举元素变成了这个类中的一个公有,静态的常量。而它们的类型则是之前通过:ushort语句所描述的 ushort类型。
  • 在这个类中还会有一个value__的公有字段用来保存一个枚举实例的当前值,它的类型当然也就是之前定义的基础类型ushort。
  • 我们对枚举实例的操作其实是直接对这个value__字段的操作。

位枚举

在上面所描述的枚举中,一个枚举的实例只能表示定义的枚举元素中的一个元素。但是有时候我们需要一个枚举实例能表示多个枚举元素。

例如:

public enum Operation
{
        Read,
        Write,
}

此时我们没有办法来表示同时具有Read和Write操作的情况。如果一定要表示那就是加一个组合元素ReadWrite来表示。但是如果枚举元素个数比较多,组合的情况就太多了。每一个组合都添加一个元素不太现实。

因此CLR提供了位枚举的功能。一个位枚举的实例可以表示多个枚举元素的组合。如下:

[Flags]
public enum Operation
{
        Read = 0x1,
        Write = 0x2,
}

Operation op = Operation.Read | Operation.Write;

我们可以通过|(或操作)来给枚举实例中添加一个枚举元素。但是如何从一个枚举元素中移除一个元素呢,那就要用到巧妙的位操作了:

op = op & (~Operation.Read)

这样则把Operation.Read从op中移除了。

ToString方法

由于在枚举定义中每一个元素都有一个名字和一个值,在使用ToString的无参方法时:

  • 普通枚举是将枚举元素的名字返回给调用者
  • 位枚举是将实例所表示的所有元素的名字用逗号分隔的形式连接起来返回给调用者
posted @ 2013-01-18 17:23  self.refactoring  阅读(310)  评论(0)    收藏  举报