建议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. OD 实验(七) - 对一个程序的破解和去广告

    程序: 这里有很多的动态链接库 双击运行程序 这个程序有次数限制 按钮也在隐藏处 主界面 退出程序,会弹出一个广告 目的: 让程序的使用次数不受限制,且没有显示次数的窗口 去除程序关闭时候的广告 逆向 ...

  2. Julia - 函数返回值

    return 返回值 要返回函数最后一个表达式的值,可以省略 return julia> function f(x, y) x + y end f (generic function with ...

  3. Dev使用技巧汇总

    C# XtraGrid的行指示器(RowIndicator)行号以及图标设置 参考网址:https://www.cnblogs.com/xuliangxing/p/6775438.html DateE ...

  4. svn关键词BASE, HEAD, COMMITTED, PREV的深入理解

    svn关键词BASE, HEAD, COMMITTED, PREV可以很方便用于日常操作中,但是很多人对他们的工作原理和方式不是太了解. 在这里我将使用用例,诠释他们的作用和意图. 先给出svn手册中 ...

  5. 第六篇 Flask 中内置的 Session

    Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...

  6. URL里面的中文参数到底转换成了什么?

    https://www.amazon.cn/s/ref=nb_sb_noss?__mk_zh_CN=%E4%BA%9A%E9%A9%AC%E9%80%8A%E7%BD%91%E7%AB%99& ...

  7. Arduino学习笔记A6(补充) - 在串口读取多个字符串,并且转换为数字数组

    功能如题目. 在串口收到逗号分割的6串数字比如 100,200,45,4,87,99 然后在6个PWM端口3, 5, 6, 9, 10, 11输出对应PWM值 代码注释很详细了,就不再说明了. ARD ...

  8. leetcode36

    public class Solution { public bool IsValidSudoku(char[,] board) { ; i < ; i++) { var dic = new D ...

  9. MantisBT 缺陷管理系统

    简介: 公司需要一套缺陷管理系统,这种系统比较热门的有 Jira.Redmine.MantisBT 等. 这次来整理一下 MantisBT,正好公司需要,以前的文档又丢失了. 下载地址:http:// ...

  10. C# 对象封装为json格式

    1 对象 public class Person { public string Name { get; set; } public int Age { get; set; } public Date ...