第十四讲 枚举
枚举类型是C#中又一种轻量级的值类型,C#用枚举来表达一组特定的值的集合行为,比如Windows窗体可选的状态,按钮控件的风格等。下面的程序伪码展示了典型的枚举用法:
public enum WritingStyle
{
Classical,
Modern,
Elegant,
}
class Essay
{
public void Write(WritingStyle writingStyle)
{
switch (writingStyle)
{
case WritingStyle.Classical:
// 古典的写作风格
break;
case WritingStyle.Modern:
// 现代的写作风格
break;
case WritingStyle.Elegant:
// 典雅的写作风格
break;
default:
throw(new System.ArgumentException("Invalid Writing Style"));
}
}
}
注意上面的枚举符号Classical, Modern, Elegant之间用逗号“,”而不是分号“;”来分隔。其中最后一个枚举值Elegant之后可以省去逗号分隔符。
和结构一样,C#中的枚举不允许也有自己的继承父类System.Enum,同样的,枚举不能被继承,也没有abstract一说。System.Enum类为枚举类型提供了很多好用的功能操作。比如我们可以通过GetName方法得到我们声明枚举值的字符串符号表示。下面的例子显示了一些比较常用的操作:
using System;
public enum WritingStyle
{
Classical,
Modern,
Elegant,
}
class Test
{
public static void
Main
()
{
WritingStyle dw=WritingStyle.Modern;
Console.WriteLine(Enum.GetName(typeof(WritingStyle),dw));
Console.WriteLine(dw.ToString());
Console.WriteLine(Enum.GetUnderlyingType(typeof(WritingStyle)));
}
}
其中的最后一行输出了System.Int32,这是怎么回事?我们知道int是System.Int32的简写形式,难道我们的WritingStyle枚举类型和整数int类型有什么关系吗?
是的,C#的枚举和整数值之间严格区分,比如我们就不能在上面的代码中作dw=1类似的赋值。但每个枚举值却的的确确都有一个整数类型的数值相对应,而且可以转换,只不过这种转换必须用明晰的转型语法来表达。我们知道在C#中整数类型有byte, sbyte, short, ushort, int, uint, long ,ulong共八种,那么C#的枚举值对应的是哪一种整数类型呢?它关系到我们的枚举类型能够容纳的枚举值的数量。实际上C#枚举类型支持这八种整数类型的任何一种,根据我们的需要,可以在声明枚举类型的时候来指定,如“public enum WritingStyle :byte”就指定了它的枚举值的整数类型为byte。该类型可以通过上面所述的Enum.GetUnderlyingType方法来获得。如果不明确指定,C#将默认采用int类型作为枚举数值的类型。既然枚举值实际上也是一种整数值,那么它的大小呢?读者将下面的代码加在上面的Main函数内,就可看到结果了。
foreach(object obj in Enum.GetValues(typeof(WritingStyle)))
{
Console.WriteLine(obj.ToString() +" : "+(int)obj);
}
上面的代码将产生以下输出:
Classical : 0
Modern : 1
Elegant : 2
可以看到,C#默认地从0起为我们的枚举值赋了一个隐含的值。当然,我们也可以自己为枚举值指定数值:
public enum WritingStyle
{
Classical=0,
Modern=10,
Elegant=100,
}
我们甚至可以象下面这样,前提是我们必须保证编译时能够计算出他们各自的数值。
public enum WritingStyle
{
Classical=0,
Modern=10+Classical,
Elegant=10+Modern,
}
枚举值也拥有象整数那样的比较,逻辑,算术等操作行为,看下面的例子:
using System;
public enum WritingStyle
{
Classical=0,
Modern=10+Classical,
Elegant=10+Modern,
}
class Test
{
public static void
Main
()
{
WritingStyle dw=WritingStyle.Modern;
Console.WriteLine(dw+10);
Console.WriteLine(dw+9);
}
}
当计算出来的数值等于某个枚举值的实际大小,那么显示的是该枚举值的符号名称,否则显示的将是整数值。