枚举类型定义了一组 “符号/值” 配对
namespace XXX
{
internal enum Color
{
White, //赋值0
Red, //赋值1
Green, //赋值2
Blue, //赋值3
Orange //赋值4
}
}
每个枚举类型都直接从System.Enum派生,后者从System.ValueType派生,所以,枚举类型是值类型,可表示成未装箱和已装箱形式。
编译枚举类型时,C#编译器会把每个符号转换成类型的一个常量字段,上面代码会被看成一下代码:
namespace XXX
{
internal struct Color : System.Enum
{ //以下是一些公共常量,它们定义了Color的符号和值
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 const Color Orange=(Color)4;
//以下是一个公共实例字段,它包含一个Color变量的值,不能写代码来直接引用这个实例字段
public Int32 value_;
}
}
简单来说,枚举类型只是一个结构,其中定义了一组常量字段和一个实例字段。常量字段会嵌入到程序集的元数据中,并可通过反射来访问。
protected void Page_Load(object sender, EventArgs e)
{
PrintEnum(Color.Orange); //vlaue_被设置为4
}
private void PrintEnum(Color color)
{
Label1.Text = color.ToString()+" "+color.ToString("D"); //Orange 4
color--; //3
Label2.Text = color.ToString()+" "+color.ToString("D"); //Blue 3
color--; //2
Label3.Text = color.ToString()+" "+color.ToString("D"); //Green 2
color = color - 3; //-1
Label4.Text = color.ToString() + " " + color.ToString("D") + " " + color.ToString("X"); //-1 -1 FFFFFFFF
}
通过上面例子,我们可以了解到 C#编译器将枚举类型视为基元类型。所以可以使用许多操作符(==,!=,<,>,<=,>=,+,-,^,&,|,~,++,--)来操纵枚举类型的实例。所有这些操作符实际作用于每个枚举类型实例内部的value_实例字段。上面枚举类型的实例调用的ToString()方法里的参数,默认是常规格式,D是十进制格式,X是十六进制格式,当value_的值不在范围内(本例范围是01234),由于找不到值对应的符号,所以常规格式只会显示值而不会显示符号。
每个枚举类型都有一个基础类型,它可以是byte,sbyte,short,ushort,int(最常用,也是C#默认选择的),uint,long,ulong C#规定只能基元类型,如果指定的是使用了FCL类型,如Int32,就会报错
以下显示了如何声明一个基础类型是byte的枚举类型:
internal enum Color : byte
{
White, //赋值0
Red, //赋值1
Green, //赋值2
Blue, //赋值3
Orange //赋值4
}
System.Enum的静态方法GetValues
private void GetEnum()
{
Color[] colors=(Color[])Enum.GetValues(typeof(Color));
foreach (Color c in colors)
{
Label5.Text += c.ToString() + " " + c.ToString("D")+"<br/>";
}
}
White 0
Red 1
Green 2
Blue 3
Orange 4
那么枚举类型是嵌套定义在需要它的类型中,还是定义成和需要它的那个类型的同级?检查FCL,会发现枚举类型通常与需要它的类同级。
定义用于位标识的枚举类型----[Flags]
仍然算是枚举类型,但一般的枚举类型表示单个数值(一个枚举类型实例只能是一种状态,如前面的要么是White要么是Red或其他的一种),而位标识需要显示的为每个符号分配一个数值,它可以代表多种状态的组合
[Flags]
internal enum MyFile
{
Open=1,
Close=2,
Save=4,
SaveClose=MyFile.Close|MyFile.Save,
Other=8
}
protected void Page_Load(object sender, EventArgs e)
{
MyFile file = MyFile.Save|MyFile.Close|MyFile.Open;
PrintBitEnum(file);
}
private void PrintBitEnum(MyFile file)
{
Label6.Text = file.ToString() + " " + file.ToString("D");
Label7.Text = ((file & MyFile.Other)==MyFile.Other).ToString();
}
Open, SaveClose 7
False
http://hi.baidu.com/billschen/blog/item/203de96053ecb0cd8db10d00.html
不是说位标识一定必须要2的整次方,但如果不是2的整次方,得到的结果会不正确(-_-!!其实就是要2的整次方)