建议110:用类来代替enum

枚举(enum)用来表示一组固定的值。例如,为了表示星期信息,我们可以定义枚举Week:

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

枚举最大的优点在于它的类型是值类型。相比较引用类型来说,它可以在关键算法中提升性能,因为它不需要创建在“堆”中。但是,如果不考虑这方面的因素,我们不妨让类(引用类型)来代替枚举。代码如下:

        class Week
{
public static readonly Week Monday = new Week();
public static readonly Week Tuesday = new Week();
//省略 private int _infoType; private Week(int infoType)
{
_infoType = infoType;
}
}

我们将类型Week的构造方法实现为private,这有效阻止了类型在外部生成类的实例,使它的行为更接近于枚举。

类Week相比枚举Week的优点在于,它能够添加方法或重写基类方法,以便提供丰富的功能。以星期为例,如果要提供更有意义的字符串,如指定Monday是星期一,对于枚举来说,这并不是天然支持的。甚至会大费周折。曾经有人实现过枚举的这种功能:

    enum Week
{
[EnumDescription("星期一")]
Monday,
[EnumDescription("星期二")]
Tuesday
} [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public sealed class EnumDescriptionAttribute : Attribute
{
private string description;
public string Description
{
get { return this.description; }
} public EnumDescriptionAttribute(string description)
: base()
{
this.description = description;
}
}
public static class EnumHelper
{
public static string GetDescription(Enum value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
string description = value.ToString();
FieldInfo fieldInfo = value.GetType().GetField(description);
EnumDescriptionAttribute[] attributes = (EnumDescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);
if (attributes != null && attributes.Length > )
{
description = attributes[].Description;
}
return description;
}
} static void Main(string[] args)
{
Console.WriteLine(EnumHelper.GetDescription(Week.Monday));
}

输出:

星期一

如果不为枚举元素加上属性EnumDescription特性,我们只能使用:

Console.WriteLine(EnumHelper.GetDescription(Week.Monday));

输出:

Monday

如果在类中,就不会有枚举的这种不方便了,因为可以通过重写object的ToString方法将问题解决。代码如下:

        static void Main(string[] args)
{
Console.WriteLine(Week.Monday);
} class Week
{
public static readonly Week Monday = new Week();
public static readonly Week Tuesday = new Week();
//省略 private int _infoType; private Week(int infoType)
{
_infoType = infoType;
} public override string ToString()
{
switch (_infoType)
{
case :
return "星期一";
case :
return "星期二";
default:
throw new Exception("不正确的星期信息!");
}
}
}

相比枚举而言,类能赋予类型更多的行为。当然,如果应用场合满足如下特性,我们就应该更多的考虑使用枚举:

  • 效率。这源于枚举是值类型。
  • 类型用于内部,不需要增加更多的行为属性。
  • 类型元素不需要提供附加的特性。

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

编写高质量代码改善C#程序的157个建议——建议110:用类来代替enum的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 编写高质量代码改善C#程序的157个建议——建议153:若抛出异常,则必须要注释

    建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会 ...

  8. 编写高质量代码改善C#程序的157个建议——建议152:最少,甚至是不要注释

    建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. ...

  9. 编写高质量代码改善C#程序的157个建议——建议151:使用事件访问器替换公开的事件成员变量

    建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass ...

  10. 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法

    建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...

随机推荐

  1. jaxp使用笔记

    XML文件的解析技术有DOM和SAX方式,在Android中还有pull解析方式,这里不再讨论 DOM解析的方式和js中的DOM操作是一致的,DOM解析一次将文档加载入内存建立树型模型,但是如果XML ...

  2. OD 实验(十七) - 对一个程序的逆向分析

    程序: 运行程序 弹出一个对话框,点击 OK 来到主界面,点击 Help -> Register Now 这是输入注册码的地方 按关闭程序的按钮 会提示剩下 30 天的使用时间 用 Ressco ...

  3. Fiddler监控面板显示ServerIP栏(Fiddler v5.0)

    Fiddler监控面板默认没有ServerIP这一栏,添加此栏方法如下: 1.点击Rules下的Customize Rules.js,会打开Fiddler ScriptEditor 2.在脚本中添加对 ...

  4. php中$_POST接收不到参数问题

    问题描述:PHP可以接收_GET._SERVER._COOKIE等参数,php://input可以读取没有处理过的POST数据,独独_POST接收不到post参数.  原因: php://input可 ...

  5. XSD 学习

    1.新建文件 Rhythmk.xsd <?xml version="1.0" encoding="utf-8"?> <xs:schema id ...

  6. RHCE7 学习里程-4用户权限,简单进程管理

    #创建用户 useradd abc 使用 vipw 命令查看 /etc/passwd 文件下 是否存在新用户 #G却换到最后一行 #创建账号的时候,默认也新建了一个组,组名跟用户名一样 groupad ...

  7. sql开启xp_cmdshell

    sql开启xp_cmdshell sp_configure reconfigure go sp_configure reconfigure go

  8. DataSnap 连接池 DSServer1Disconnect

    DataSnap Server DSServer1Disconnect 这个函数什么时候执行? void __fastcall TServerContainer1::DSServer1Disconne ...

  9. e s6 知识点

    http://es6.ruanyifeng.com/#docs/reflect 1.资料对es6箭头函数中的this总结:箭头函数中的this指向的是 定义时的this,而不是 执行时的this.

  10. mediawiki的安装

    1. yum install httpd php pcre php-mysql php-pear php-pecl-apc mysql-server ImageMagick sendmail php- ...