C# 语言规范_版本5.0 (第14章 枚举)

1. 枚举

枚举类型 (enum type) 是一种独特的值类型(第 4.1 节),它用于声明一组命名的常量。

下面的示例

enum Color
{
Red,
Green,
Blue
}

声明一个名为 Color 的枚举类型,该类型具有三个成员:Red、Green 和 Blue。

1.1 枚举声明

枚举声明用于声明新的枚举类型。枚举声明以关键字 enum 开始,然后定义该枚举的名称、可访问性、基础类型和成员。

enum-declaration:
attributesopt   enum-modifiersopt   enum  
identifier   enum-baseopt   enum-body  
;opt

enum-base:
:  
integral-type

enum-body:
{  
enum-member-declarationsopt  
}
{  
enum-member-declarations   ,   }

每个枚举类型都有一个相应的整型类型,称为该枚举类型的基础类型 (underlying type)。此基础类型必须能够表示该枚举中定义的所有枚举数值。枚举声明可以显式地声明 byte、sbyte、short、ushort、int、uint、long 或 ulong 的基础类型。请注意 char 不能用作基础类型。没有显式地声明基础类型的枚举声明意味着所对应的基础类型是 int。

下面的示例

enum Color:
long
{
Red,
Green,
Blue
}

声明了一个基础类型为 long 的枚举。开发人员可以像本示例一样选择使用 long 基础类型,以便能够使用在 long 范围内而不是在 int 范围内的值,或者保留此选项供将来使用。

1.2 枚举修饰符

enum-declaration 可以根据需要包含一个枚举修饰符序列:

enum-modifiers:
enum-modifier
enum-modifiers   enum-modifier

enum-modifier:
new
public
protected
internal
private

同一修饰符在一个枚举声明中多次出现属于编译时错误。

枚举声明的修饰符与类声明(第 10.1.1 节)的修饰符具有同样的意义。然而请注意,在枚举声明中不允许使用 abstract 和 sealed 修饰符。枚举不能是抽象的,也不允许派生。

1.3 枚举成员

枚举类型声明体用于定义零个或多个枚举成员,这些成员是该枚举类型的命名常量。任意两个枚举成员不能具有相同的名称。

enum-member-declarations:
enum-member-declaration
enum-member-declarations   ,   enum-member-declaration

enum-member-declaration:
attributesopt   identifier
attributesopt  
identifier   =   constant-expression

每个枚举成员均具有相关联的常量值。此值的类型就是包含了它的那个枚举的基础类型。每个枚举成员的常量值必须在该枚举的基础类型的范围之内。下面的示例

enum Color:
uint
{
Red = -1,
Green = -2,
Blue = -3
}

会导致编译时错误,因为常量值 -1、-2 和 –3 不处于基础整型 uint 的范围中。

多个枚举成员可以共享同一个关联值。下面的示例

enum Color
{
Red,
Green,
Blue,

Max = Blue
}

演示一个枚举,其中的两个枚举成员(Blue 和 Max)具有相同的关联值。

一个枚举成员的关联值或隐式地、或显式地被赋值。如果枚举成员的声明中具有 constant-expression 初始值设定项,则该常量表达式的值(它隐式转换为枚举的基础类型)就是该枚举成员的关联值。如果枚举成员的声明不具有初始值设定项,则它的关联值按下面规则隐式地设置:

  • 如果枚举成员是在枚举类型中声明的第一个枚举成员,则它的关联值为零。
  • 否则,枚举成员的关联值是通过将前一个枚举成员(按照文本顺序)的关联值加 1 得到的。这样增加后的值必须在该基础类型可表示的值的范围内;否则,会出现编译时错误。

下面的示例

using System;

enum Color
{
Red,
Green = 10,
Blue
}

class Test
{
static void Main() {
     Console.WriteLine(StringFromColor(Color.Red));
     Console.WriteLine(StringFromColor(Color.Green));
     Console.WriteLine(StringFromColor(Color.Blue));
}

static string StringFromColor(Color c) {
     switch (c) {
        case Color.Red:
            return String.Format("Red
= {0}", (int) c);

case Color.Green:
            return
String.Format("Green = {0}", (int) c);

case Color.Blue:
            return
String.Format("Blue = {0}", (int) c);

default:
            return "Invalid
color";
     }
}
}

输出枚举成员名称和它们的关联值。输出为:

Red = 0
Green = 10
Blue = 11

原因如下:

  • 枚举成员
    Red 被自动赋予零值(因为它不具有初始值设定项并且是第一个枚举成员);
  • 枚举成员
    Green 被显式赋予值 10;
  • 而枚举成员
    Blue 被自动赋予比文本上位于它前面的成员大 1 的值。

枚举成员的关联值不能直接或间接地使用它自己的关联枚举成员的值。除了这个循环性限制外,枚举成员初始值设定项可以*地引用其他的枚举成员初始值设定项,而不必考虑它们所在的文本位置的排列顺序。在枚举成员初始值设定项内,其他枚举成员的值始终被视为属于所对应的基础类型,因此在引用其他枚举成员时,没有必要使用强制转换。

下面的示例

enum Circular
{
A = B,
B
}

产生编译时错误,因为 A 和 B 的声明是循环的。A 显式依赖于 B,而 B 隐式依赖于 A。

枚举成员的命名方式和作用范围与类中的字段完全类似。枚举成员的范围是包含了它的枚举类型的体。在该范围内,枚举成员可以用它们的简单名称引用。在所有其他代码中,枚举成员的名称必须用它的枚举类型的名称限定。枚举成员不具有任何声明可访问性,如果一个枚举类型是可访问的,则它所含的所有枚举成员都是可访问的。

1.4 System.Enum
类型

System.Enum 类型是所有枚举类型的抽象基类(它是一种与枚举类型的基础类型不同的独特类型),并且从 System.Enum 继承的成员在任何枚举类型中都可用。存在从任何枚举类型到 System.Enum 的装箱转换(第 4.3.1 节),并且存在从 System.Enum 到任何枚举类型的取消装箱转换(第 4.3.2 节)。

请注意,System.Enum 本身不是
enum-type。而是
class-type,所有
enum-type 都是从它派生的。类型 System.Enum 从类型 System.ValueType(第 4.1.1 节)继承,而后者又从类型 object
继承。在运行时,类型 System.Enum 的值可以是 null 或是对任何枚举类型的装箱值的引用。

1.5 枚举值和运算

每个枚举类型都定义了一个不同的类型;需要使用显式枚举转换(第 6.2.2 节)在枚举类型和整型之间或在两个枚举类型之间进行转换。一个枚举类型的值域不受它的枚举成员限制。具体而言,一个枚举的基础类型的任何一个值都可以被强制转换为该枚举类型,成为该枚举类型的一个独特的有效值。

枚举成员所属的类型就是声明了它们的那个枚举(出现在其他枚举成员初始值设定项中时除外:请参见第 14.3 节)。在枚举类型 E 中声明且关联值为 v 的枚举成员的值为 (E)v。

以下运算符可用于枚举类型的值:==、!=、<、>、<=、>=(第 7.10.5 节)、二元 +(第 7.8.4 节)、二元 ‑(第 7.8.5 节)^、&、|(第 7.11.2 节)、~(第 7.7.4 节)、++ 和 --(第 7.6.9 节和第 7.7.5 节)。

每个枚举类型自动派生自类 System.Enum (后者又派生自 System.ValueType 和 object) \t "See also Enum" \t "See also Enum"  \t "See also Enum"  \t "See Enum" \t "See also
Enum"  \t "See Enum" 。因此,此类的派生方法和属性可以用在枚举类型的值上。

上一篇:C++ Primer学习笔记 - 第16章 模板与泛型编程


下一篇:MySQL 数据类型