建议8: 避免给枚举类型的元素提供显式的值

一般情况下,没有必要给枚举类型的元素提供显式的值。创建枚举的理由之一,就是为了代替使用实际的数值。不正确地为枚举类型的元素设定显式的值,会带来意想不到的错误。

如果为建议7中的枚举类型Week增加一个元素,代码如下所示:

    enum Week
{
Monday = ,
Tuesday = ,
ValueTemp,
Wednesday = ,
Thursday = ,
Friday = ,
Saturday = ,
Sunday =
}

设想一下ValueTemp的值会是什么?为了验证结果,我们来看这段代码的输出:

    Week week = Week.ValueTemp;
Console.WriteLine(week);
Console.WriteLine(week == Week.Wednesday);

输出为:

    Wednesday
True

很遗憾,我们明明为Week赋值为ValueTemp,可是得到的结果却是Wednesday。

事实上,如果为枚举类型显式地赋过值,那么很有可能在下个版本中,你为了某些增加的需要,会为枚举添加元素,在这个时候,就像我们为Week增加元素ValueTemp一样,极有可能会一不小心增加一个无效值。

上一个建议中已经讲到如果没有为元素显式赋值,编译器会逐个为元素的值+1。当编译器发现元素ValueTemp的时候,它会自动在Tuesday = 2的基础上+1,所以,实际ValueTemp的值和Wednesday的值都是3。而枚举本身所包括的枚举元素都是值类型,所以产生了上面的输出。

从上面的例子我们应该已经注意到,枚举元素允许设定重复的值。所以,当我们看到下面这段代码的输出时,应该不会感到吃惊:

    enum Temp
{
Value1 = ,
Value2 =
}
    private static void NewMethod2()
{
Temp temp1 = Temp.Value1;
Temp temp2 = Temp.Value2;
Console.WriteLine(temp1 == temp2);
Console.WriteLine(temp1.Equals(temp2));
Console.WriteLine(temp1.CompareTo(temp2));
Console.WriteLine(temp1 == Temp.Value1);
Console.WriteLine(temp1 == Temp.Value2);
}

输出为:

    True
True True
True

注意 本建议也有例外。例如,当为一个枚举类型指定System.FlagsAttribute 属性时,就意味着可以对这些值执行 AND、OR、NOT 和 XOR 按位运算,这样一来,就要求枚举的每个元素的值都是 2 的若干次幂,指数依次递增。如Week的版本就应该为:

    [Flags]
enum Week
{
None = 0x0,
Monday = 0x1,
Tuesday = 0x2,
Wednesday = 0x4,
Thursday = 0x8,
Friday = 0x10,
Saturday = 0x20,
Sunday = 0x40
} class MyClass
{
Week week = Week.Thursday | Week.Sunday;
}

输出为:

Thursday, Sunday

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

编写高质量代码改善C#程序的157个建议——建议8: 避免给枚举类型的元素提供显式的值的更多相关文章

  1. 编写高质量代码改善C#程序的157个建议——导航开篇

    前言 由于最近工作重心的转移,原来和几个同事一起开发的项目也已经上线了,而新项目就是在现有的项目基础上进行优化延伸扩展.打个比方,现在已经上线的项目行政案件的Web管理网站(代码还没那么多相比较即将要 ...

  2. 编写高质量代码改善C#程序的157个建议读书笔记【1-10】

    开篇 学生时代,老师常说,好记性不如烂笔头,事实上确实如此,有些知识你在学习的时候确实滚瓜烂熟,但是时间一长又不常用了,可能就生疏了,甚至下次有机会使用到的时候,还需要上网查找资料,所以,还不如常常摘 ...

  3. 编写高质量代码改善C#程序的157个建议

    1.使用StringBuilder或者使用string.Format("{0}{1}{2}{3}", a, b, c, d)拼接字符串. 2.使用默认转型方法,比如使用类型内置的P ...

  4. 编写高质量代码改善C#程序的157个建议[1-3]

    原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理 ...

  5. 读书--编写高质量代码 改善C#程序的157个建议

    最近读了陆敏技写的一本书<<编写高质量代码  改善C#程序的157个建议>>书写的很好.我还看了他的博客http://www.cnblogs.com/luminji . 前面部 ...

  6. 编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试

    建议157:从写第一个界面开始,就进行自动化测试 如果说单元测试是白盒测试,那么自动化测试就是黑盒测试.黑盒测试要求捕捉界面上的控件句柄,并对其进行编码,以达到模拟人工操作的目的.具体的自动化测试请学 ...

  7. 编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本

    建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能: ...

  8. 编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码

    建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的 ...

  9. 编写高质量代码改善C#程序的157个建议——建议154:不要过度设计,在敏捷中体会重构的乐趣

    建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个 ...

随机推荐

  1. linux下创建与删除用户详细步骤 ***

    linux下用户的操作还是相对容易理解的,基本操作如下: 1.新增用户 只有root用户能创建新用户 #useradd user1 新建后将会在/home目录下生成一个与用户名相同的用户主目录.同时会 ...

  2. EM64T和64位是不是一个概念啊?他们有什么区别啊,怎么区分啊?

    首先我们要解决什么是64位这个问题.究竟什么是64位处理器呢?64 bit是相对于32 Bit而言的,这个位数指的是CPU GPRs(General-Purpose Registers,通用寄存器)数 ...

  3. CIDR地址分类

    CIDR(Classless Inter Domain Routing)改进了传统的IPv4地址分类.传统的IP分类将IP地址直接对应为默认的分类,从而将Internet分割为网络.CIDR在路由表中 ...

  4. CCPC2018-湖南全国邀请赛 G String Transformation

    G.String Transformation 题目描述 Bobo has a string S = s1 s2...sn consists of letter a , b and c . He ca ...

  5. Spring XML和Annotation混合配置的时候,XML中Bean名称写错会导致启动异常不打印、死循环

    今天做Tomcat迁移Spring Boot,遇到一个坑.启动没有错误,CPU特别高 经过把堆栈kill -3 打印出来,发现堆栈特别长(没有死循环),所有的堆栈信息都集中在org.springfra ...

  6. 1009 Product of Polynomials

    题意:模拟多项式相乘 思路:略.有一个注意点,题目中说指数最大为1000,当两个多项式相乘后,指数最大就为2000,这一点不注意会出现段错误. 代码: #include <cstdio> ...

  7. 南京邮电大学网络攻防平台WEB题

    平台地址:http://ctf.nuptsast.com/ 签到题: 右键查看源代码,得到flag md5 collision: 传入的a的md5值要为0e开头的,但不能是QNKCDZO,百度一个0e ...

  8. 如何查看路由器中的pppoe拨号密码?

    1 2 3 4 5 6 分步阅读 有时候把宽带的账号密码给忘了,进路由器的拨号页面看了一下,账号能看到,就密码是以“*”号形式显示的,没法用“肉眼”识别出来,怎么办呢?难道真的非得打电话问运营商不可? ...

  9. Python——Dict

    Python字典(Dictionary) 字典是一种可变容器模型,可存储任意类型对象. 字典的每个键值(key => value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花 ...

  10. wince驱动开发入门

    因为课题前期调研没做好,用的CPU板卡和数据采集卡来自两个部门.加上买的是裸板,自己定制的OS,技术支持不爱搭理.所以给的AI板卡的驱动一直装不上,自己在郁闷中寻找答案,就扎进了wince驱动的知识库 ...