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# 语言规范_版本5.0 (第14章 枚举)的更多相关文章

  1. C# 语言规范_版本5.0 (第2章 词法结构)

    1. 词法结构 1.1 程序 C# 程序 (program) 由一个或多个源文件 (source file) 组成,源文件的正式名称是编译单元 (compilation unit)(第 9.1 节). ...

  2. C# 语言规范_版本5.0 (第10章 类)

    1. 类 类是一种数据结构,它可以包含数据成员(常量和字段).函数成员(方法.属性.事件.索引器.运算符.实例构造函数.静态构造函数和析构函数)以及嵌套类型.类类型支持继承,继承是一种机制,它使派生类 ...

  3. C# 语言规范_版本5.0 (第3章 基本概念)

    1. 基本概念 1.1 应用程序启动 具有入口点 (entry point) 的程序集称为应用程序 (application).应用程序运行时,将创建新的应用程序域 (application doma ...

  4. C# 语言规范_版本5.0 (第18章 不安全代码)

    1. 不安全代码 **(注:此章对于跨多语言编程开发非常重要,如遇异常无法完成跨语言,建议使用此种方式.) 如前面几章所定义,核心 C# 语言没有将指针列入它所支持的数据类型,从而与 C 和 C++ ...

  5. C# 语言规范_版本5.0 (第17章 特性)

    1. 特性 C# 语言的一个重要特征是使程序员能够为程序中定义的实体指定声明性信息.例如,类中方法的可访问性是通过使用 method-modifiers(public.protected.intern ...

  6. C# 语言规范_版本5.0 (第11章 结构)

    1. 结构 结构与类的相似之处在于,它们都表示可以包含数据成员和函数成员的数据结构.但是,与类不同,结构是一种值类型,并且不需要堆分配.结构类型的变量直接包含了该结构的数据,而类类型的变量所包含的只是 ...

  7. C# 语言规范_版本5.0 (第8章 语句)

    1. 语句 C# 提供各种语句.使用过 C 和 C++ 编程的开发人员熟悉其中大多数语句. statement: labeled-statement declaration-statement emb ...

  8. C# 语言规范_版本5.0 (第7章 表达式)

    1. 表达式 表达式是一个运算符和操作数的序列.本章定义语法.操作数和运算符的计算顺序以及表达式的含义. 1.1 表达式的分类 一个表达式可归类为下列类别之一: 值.每个值都有关联的类型. 变量.每个 ...

  9. C# 语言规范_版本5.0 (第6章 转换)

    1. 转换 转换(conversion) 使表达式可以被视为一种特定类型.转换可导致将给定类型的表达式视为具有不同的类型,或其可导致没有类型的表达式获得一种类型.转换可以是隐式的 (implicit) ...

随机推荐

  1. java文件上传--基于ajaxFileUpload+struts2

    jQuery插件ajaxFileUpload可以实现ajax文件上传,使用非常简单. 下面做一个简单的demo(以上传图片为例),实现图片上传,图片显示,图片下载 注:以下的代码是在项目的基础上进行开 ...

  2. struts整合spring整合hibernate

    1, web.xml中配置spring监听类 <listener> <listener-class>org.springframework.web.context.Contex ...

  3. Exchange 2016 创建日程,远程服务器返回错误: (401) 未经授权

    背景:在测试环境中一切正常,使用的是Exchange2013,上生产环境Exchange2016,部署后产生如下错误: Microsoft.Exchange.WebServices.Data.Serv ...

  4. jQuery焦点图切换特效插件封装

    网站焦点图是一种网站内容的展现形式,可简单理解为一张图片或多张图片展现在网页上就是网站焦点图.在网站很明显的位置,用图片组合播放的形式,类似焦点新闻的意思只不过加上了图片.一般多使用在网站首页版面或频 ...

  5. 配置 SQL Server Email 发送以及 Job 的 Notification通知功能

    配置 SQL Server Email 发送以及 Job 的 Notification通知功能 在与数据库相关的项目中, 比如像数据库维护, 性能警报, 程序出错警报或通知都会使用到在 SQL Ser ...

  6. iOS状态变更

    iOS应用状态变更 应用启动周期 当应用启动时,它从未运行状态到活跃或后台状态,简单地过渡未激活状态.作为启动周期的一部分,系统为应用创建一个过程和主进程并在主进程上调用应用的主函数.来自你的Xcod ...

  7. python cookbook学习1

    python cookbook学习笔记 第一章 文本(1) 1.1每次处理一个字符(即每次处理一个字符的方式处理字符串) print list('theString') #方法一,转列表 结果:['t ...

  8. html5基础的常用的技巧

    html5基础的常用的技巧 1. 新的Doctype声明 XHTML的声明太长了,我相信很少会有前端开发人员能手写出这个Doctype声明. <!DOCTYPE html PUBLIC &quo ...

  9. Python 入门介绍

    写在前面 开始介绍Python之前, 先回顾一下编译型语言和解释型语言的概念和区别. 计算机能直接识别只能是机器语言, 所以使用高级语言编写的程序必须翻译成机器语言,计算机才能执行. 翻译的方式有两种 ...

  10. .Net程序员学用Oracle系列(1):导航目录

    本人从事基于 Oracle 的 .Net 企业级开发近三年,在此之前学习和使用的都是 (MS)SQL Server.未曾系统的了解过 Oracle,所以长时间感到各种不习惯.不方便.怪异和不解,常会遇 ...