深入浅出OOP(六): 理解C#的Enums
MSDN定义:枚举类型(也称为枚举)为定义一组可以赋给变量的命名整数常量提供了一种有效的方法。 例如,假设您必须定义一个变量,该变量的值表示一周中的一天。
该变量只能存储七个有意义的值。 若要定义这些值,可以使用枚举类型。枚举类型是使用 enum 关键字声明的。
从OOP上来说,枚举的角色和和class一样,它创建了一种新的数据类型。
1: namespace Enums
2: {
3: class Program
4: {
5: static void Main(string[] args)
6: {
7: }
8: }
9:
10: enum Color
11: {
12: Yellow,
13: Blue,
14: Brown,
15: Green
16: }
17: }
上面的代码,我们使用enum的关键字,创建了新的数据类型Color,并包含4个值:Yellow
, Blue
, Brown和
Green。下面的例子我们给予Color枚举。
直接输出枚举,则可得到枚举的字符
1: using System;
2: namespace Enums
3: {
4: class Program
5: {
6: static void Main(string[] args)
7: {
8: Console.WriteLine(Color.Yellow);
9: Console.ReadLine();
10: }
11: }
12:
13: enum Color
14: {
15: Yellow,
16: Blue,
17: Brown,
18: Green
19: }
20: }
运行程序,输出:
Yellow
强转为int型,输出试试看:
1: using System;
2: namespace Enums
3: {
4: class Program
5: {
6: static void Main(string[] args)
7: {
8: Console.WriteLine((int)Color.Yellow);
9: Console.ReadLine();
10: }
11: }
12:
13: enum Color
14: {
15: Yellow,
16: Blue,
17: Brown,
18: Green
19: }
20: }
结果输出:
0
从上面的例子中,我们可以看到枚举的使用,如同static变量一样,可被直接使用。如不用转换则默认输出枚举定义的字符,强转后
则输出枚举对应的数字值---故枚举可表达恒量数值,或者命名的字符串标示。
基础数据类型
1: using System;
2: namespace Enums
3: {
4: class Program
5: {
6: static void Main(string[] args)
7: {
8: Console.WriteLine((byte)Color.Yellow);
9: Console.WriteLine((byte)Color.Blue);
10: Console.ReadLine();
11: }
12: }
13:
14: enum Color:byte
15: {
16: Yellow,
17: Blue,
18: Brown,
19: Green
20: }
21: }
结果输出为:
0
1
这里唯一做的修改是枚举Color继承自byte ,而不是默认的int型。
枚举可继承自数值型类型,如
long
, ulong
, short
, ushort
, int
, uint
, byte
何sbyte。但是无法继承自char类型。
枚举可被枚举继承吗?
枚举可被枚举继承吗?
1: using System;
2: namespace Enums
3: {
4: class Program
5: {
6: static void Main(string[] args)
7: {
8: Console.WriteLine((byte)Color.Yellow);
9: Console.WriteLine((byte)Color.Blue);
10: Console.ReadLine();
11: }
12: }
13:
14: enum Color:byte
15: {
16: Yellow,
17: Blue,
18: Brown,
19: Green
20:
21: }
22:
23: enum Shades:Color
24: {
25:
26: }
27: }
编译,报错:
Type
byte
,sbyte
,short
,ushort
,int
,uint
,long
, orulong
expected.
枚举可被class继承吗?
1: enum Color:byte
2: {
3: Yellow,
4: Blue,
5: Brown,
6: Green
7: }
8:
9: class Derived:Color
10: {
11:
12: }
编译报错:
'Enums.Derived': cannot derive from sealed type 'Enums.Color'
接下来,我们看看枚举和这3个接口的关系:IComparable
, IFormattable 和
IConvertible。
A. IComparable
1: using System;
2:
3: namespace Enums
4: {
5: internal enum Color
6: {
7: Yellow,
8: Blue,
9: Green
10: }
11:
12: internal class Program
13: {
14: private static void Main(string[] args)
15: {
16: Console.WriteLine(Color.Yellow.CompareTo(Color.Blue));
17: Console.WriteLine(Color.Blue.CompareTo(Color.Green));
18: Console.WriteLine(Color.Blue.CompareTo(Color.Yellow));
19: Console.WriteLine(Color.Green.CompareTo(Color.Green));
20: Console.ReadLine();
21: }
22: }
23: }
结果输出:
-1
-1
1
0
-1表示小于关系,0表示等于关系,1表示大于关系。这里标明了enum默认继承了IComparable接口,故有CompareTo()函数。
B. IFormattable
1: using System;
2:
3: namespace Enums
4: {
5: internal enum Color
6: {
7: Yellow,
8: Blue,
9: Green
10: }
11:
12: internal class Program
13: {
14: private static void Main(string[] args)
15: {
16: System.Console.WriteLine(Color.Format(typeof(Color), Color.Green, "X"));
17: System.Console.WriteLine(Color.Format(typeof(Color), Color.Green, "d"));
18: Console.ReadLine();
19: }
20: }
21: }
结果输出:
00000002
2
Format方法继承自IFormatter 接口,它是一个static函数,因此可以被枚举Color直接使用。format需要传入3个参数,第一个是枚举的类型,
第二个参数是枚举值,第三个是格式化标示---二进制、十进制等。
C. IConvertible
1: Hide Copy Code
2: using System;
3:
4: namespace Enums
5: {
6: enum Color
7: {
8: Yellow,
9: Blue,
10: Green
11: }
12:
13: internal class Program
14: {
15: private static void Main(string[] args)
16: {
17: string[] names;
18: names = Color.GetNames(typeof (Color));
19: foreach (var name in names)
20: {
21: Console.WriteLine(name);
22: }
23: Console.ReadLine();
24: }
25: }
26: }
27:
结果输出:
Yellow
Blue
Green
GetNames函数是枚举Color的静态方法,用于获得枚举所有的字符标示名称集合。
同理也可使用ToString输出枚举的字符标示:
1: using System;
2:
3: namespace Enums
4: {
5: enum Color
6: {
7: Yellow,
8: Blue,
9: Green
10: }
11:
12: internal class Program
13: {
14: private static void Main(string[] args)
15: {
16: Console.WriteLine(Color.Blue.ToString());
17: Console.WriteLine(Color.Green.ToString());
18: Console.ReadLine();
19: }
20: }
21: }
显示输出:
Blue
Green
上面的例子显示,枚举可在int和string直接转换,这个特性是枚举使用中非常重要的一个功能。
试试看,枚举的字符标示是否可以重复定义:
1: using System;
2: namespace Enums
3: {
4: class Program
5: {
6: static void Main(string[] args)
7: {
8: Console.WriteLine((byte)Color.Yellow);
9: Console.WriteLine((byte)Color.Blue);
10: Console.ReadLine();
11: }
12: }
13:
14: enum Color
15: {
16: Yellow,
17: Blue,
18: Brown,
19: Green,
20: Blue
21: }
22: }
编译报错,结果:
Compile time error: The type 'Enums.Color' already contains a definition for 'Blue'
可见枚举中不能定义重复的字符标示。
再看另外一个例子:
1: using System;
2: namespace Enums
3: {
4: class Program
5: {
6: static void Main(string[] args)
7: {
8: Console.WriteLine((int)Color.Yellow);
9: Console.WriteLine((int)Color.Blue);
10: Console.WriteLine((int)Color.Brown);
11: Console.WriteLine((int)Color.Green);
12:
13: Console.ReadLine();
14: }
15: }
16:
17: enum Color
18: {
19: Yellow =2,
20: Blue,
21: Brown=9,
22: Green,
23:
24: }
25: }
结果:
2
3
9
10
从结果看,我们可以在枚举定义的时候重新指定数值,如我们指定了yellow为2,则Blue默认为Yellow+1,为3. 下来,我们指定了Brown为9,则
其下的Green为Brown + 1,为10。 这是一个有趣的enum特性。
如指定的数据类型超过枚举的定义类型,如何?
1: using System;
2: namespace Enums
3: {
4: class Program
5: {
6: static void Main(string[] args)
7: {
8:
9: }
10: }
11:
12: enum Color:byte
13: {
14: Yellow =300 ,
15: Blue,
16: Brown=9,
17: Green,
18: }
19: }
编译报错:
Compile time error: Constant value '300' cannot be converted to a 'byte'
300超出了byte数据类型的范围,故报错。 枚举的类型检测非常好,在项目使用中很实用的功能。
枚举引用代码
1: using System;
2: namespace Enums
3: {
4: class Program
5: {
6: static void Main(string[] args)
7: {
8: Console.WriteLine((int)Color.Yellow);
9: Console.WriteLine((int)Color.Blue);
10: Console.WriteLine((int)Color.Brown);
11: Console.WriteLine((int)Color.Green);
12:
13: Console.ReadLine();
14: }
15: }
16:
17: enum Color
18: {
19: Yellow = 2,
20: Blue,
21: Brown = 9,
22: Green = Yellow
23: }
24: }
结果输出:
2
3
9
2
这里,我们定义Green的值,引用了Color的Yellow枚举值。
枚举,是否可以在外面修改枚举值:
1: using System;
2: namespace Enums
3: {
4: class Program
5: {
6: static void Main(string[] args)
7: {
8: Color.Yellow = 3;
9: }
10: }
11:
12: enum Color
13: {
14: Yellow = 2,
15: Blue,
16: Brown = 9,
17: Green = Yellow
18: }
19: }
运行结果:
Compile time error: The left-hand side of an assignment must be a variable, property or indexer
编译报错了。可见枚举数值是常量,仅在初始化的时候确定,外部无法动态修改。
那么,枚举是否可以循环依赖?
1: using System;
2:
3: namespace Enums
4: {
5: internal enum Color
6: {
7: Yellow=Blue,
8: Blue
9: }
10:
11: internal class Program
12: {
13: private static void Main(string[] args)
14: {
15: }
16: }
17: }
编译结果:
Compile time error: The evaluation of the constant value for 'Enums.Color.Yellow' involves a circular definition
保留关键字
1: using System;
2:
3: namespace Enums
4: {
5: enum Color
6: {
7: value__
8: }
9:
10: internal class Program
11: {
12: private static void Main(string[] args)
13: {
14:
15: }
16: }
17: }
编译报错:
Compile time error: The enumerator name 'value__' is reserved and cannot be used
原因很简单,这里的value__是保留关键字。
枚举小结:
- enum表达了恒定的数值,枚举类型可以用字符串标示
- 无法声明char基础类型的枚举
- enum仅仅能继承自
byte
,sbyte
,short
,ushort
,int
,uint
,long
, 或ulong数据类型
默认的,enum是一个sealed类,既无法被继承
enum类型隐式实现了System.Enum
enum类型继承了3个接口:
IComparable
,IFormattable和
IConvertible
enum中,数字和字符串可以互相转换
enum的值可被初始化为同样的值
enum的值要在初始化时候确定
enum中,'
value__
'关键字不能使用
原文:Diving in OOP (Day 6): Understanding Enums in C# (A Practical Approach)
文章目录:
- 深入浅出OOP(一): 多态和继承(早期绑定/编译时多态)
- 深入浅出OOP(二): 多态和继承(继承)
- 深入浅出OOP(三): 多态和继承(动态绑定/运行时多态)
- 深入浅出OOP(四): 多态和继承(抽象类)
- 深入浅出OOP(五): C#访问修饰符(Public/Private/Protected/Internal/Sealed/Constants)
- 深入浅出OOP(六): 理解C#的Enums
深入浅出OOP(六): 理解C#的Enums的更多相关文章
- 网络编程懒人入门(六):深入浅出,全面理解HTTP协议
本文引用了自简书作者“涤生_Woo”的文章,内容有删减,感谢原作者的分享. 1.前言 HTTP(全称超文本传输协议,英文全称HyperText Transfer Protocol)是互联网上应用最为广 ...
- 深入浅出OOP(五): C#访问修饰符(Public/Private/Protected/Internal/Sealed/Constants)
访问修饰符(或者叫访问控制符)是面向对象语言的特性之一,用于对类.类成员函数.类成员变量进行访问控制.同时,访问控制符也是语法保留关键字,用于封装组件. Public, Private, Protec ...
- 深入浅出OOP(二): 多态和继承(继承)
本文是深入浅出OOP第二篇,主要说说继承的话题. 继承的介绍 在OOP中,继承有如下的定义: 继承是一种OOP的机制,用于派生继承预定义的类 在这个继承关系中,预定义的类是基类,新类是子类 继承常常用 ...
- JavaScript--我发现,原来你是这样的JS:面向对象编程OOP[1]--(理解对象和对象属性类型)
一.介绍 老铁们,这次是JS的面向对象的编程OOP(虽然我没有对象,心累啊,但是可以自己创建啊,哈哈). JS高程里第六章的内容,这章内容在我看来是JS中很难理解的一部分.所以分成三篇博客来逐个理清. ...
- JS--我发现,原来你是这样的JS:面向对象编程OOP[1]--(理解对象和对象属性类型)
一.介绍 老铁们,这次是JS的面向对象的编程OOP(虽然我没有对象,心累啊,但是可以自己创建啊,哈哈). JS高程里第六章的内容,这章内容在我看来是JS中很难理解的一部分.所以分成三篇博客来逐个理清. ...
- iOS - 对OOA、OOD、OOP的理解
很多人在求职的时候,会遇到一个这样的问题:“对OOD/OOP有较深的理解”,这个时候有人就会问OOD.OOP是什么呢?那么今天咱们就一块来看一下OOA.OOD.OOP到底是什么! (一)OOA--面向 ...
- 深入浅出OOP(一): 多态和继承(早期绑定/编译时多态)
在本系列中,我们以CodeProject上比较火的OOP系列博客为主,进行OOP深入浅出展现. 无论作为软件设计的高手.或者菜鸟,对于架构设计而言,均需要多次重构.取舍,以有利于整个软件项目的健康构建 ...
- 我个人对OOP的理解
OOP面向对象的思维:pay1:封装 A.避免使用非法数据赋值 B.保证数据的完整性 C.避免类内部发生修改的时候,导致整个程序的修改 pay2:继承 A.继承模拟了现实世界的关系,OOP中强调一切皆 ...
- C++——OOP面向对象理解
从Rob Pike 的 Google+上的一个推看到了一篇叫<Understanding Object Oriented Programming>的文章,我先把这篇文章简述一下,然后再说说 ...
随机推荐
- 解决关于ArcGIS10.2服务手动启动的问题
解决关于ArcGIS10.2服务手动启动的问题 C:\program files\arcgis\license10.2\bin> lmgrd -z -c service.txt新建一文本,将上面 ...
- 利用js对象的特性,去掉数组中的重复项
- PLAN表
用得较多的PLAN表有以下三个ABPPMGR:MANUFACTURINGPLN.SHIPMENTPLAN.PROCUREMENTPLAN .这三个表都是执行StartFP中的exportFP进行数据导 ...
- redis与memcached比较
引用自:http://blog.csdn.net/e_wsq/article/details/23551799 最近需要用no-sql数据库来保存大量的数据,插入和查询都比较频繁,相对而言查询更加频繁 ...
- 缓存大全(Memcached、redis、RabbitMQ )
Memcached: 简介.安装.使用 python操作Memcached Memcached天生支持集群 Redis: 简介.安装.使用.实例 Python操作Redis String.Hash.L ...
- asp.net 去掉重复的querystring
string[] vs = HttpContext.Current.Request.QueryString.GetValues(key); if (vs.Leng ...
- 基于Jquery-ui的自动补全
1.添加CSS和JS引用 <script type="text/javascript" src="javascript/jquery-1.7.min.js" ...
- KMP字符串匹配算法
static void Main(string[] args) { var d = KMP("abcabcadabc55abcabcadabc55", "abcabcad ...
- Java如何将html转以后的字符转化成正常显示的字符
String str = "“!@#¥%……&——+”";//“!@#¥%……&——+” 中文状态下的标点符号,进过html转换了 String convStr ...
- 在UTF8(linux)下,逆置汉字字符串
#include <stdio.h> int main() { char c[]="我是如此热爱编程!"; ,min=,max; while(c[index]) { i ...