背景

在我们的日常开发中,我们会经常使用枚举类型。有时我们只需要显示枚举的值或者枚举值对应名称, 但是在某些场景下,我们可能需要将枚举值显示为不同的字符串。

例: 当前我们有如下枚举Level

	public enum Level
{
//Bad
B = -1, //Normal
N = 0, //Good
G = 1, //Very Good
VG = 2
}

这个枚举有4个可选值B, N, G, VG。 现在我们希望用Bad, Normal, Good, Very Good作为B, N, G, VG的显示值。

那我们会怎么做呢?通常我们最常想到的就是针对Level枚举类型编写一个扩展方法。

    public static class LevelEnumExtension
{
public static string ToDescription(this Level level)
{
switch (level)
{
case Level.B:
return "Bad";
case Level.G:
return "Good";
case Level.N:
return "Normal";
case Level.VG:
return "Very Good";
default:
return "Normal";
}
}
}

以上的代码在我们的项目中很常用。但是这里有2个潜在的问题:

  • 我们的项目中可能不止一种枚举类型,所以我们可能就需要为每一种类型都添加一个对应的扩展方法。
  • 枚举值和枚举的显示值的代码位置是分离的,如果你查找枚举值对应的显示值,你就要先去找到对应的枚举扩展方法。

那么如何改进这部分代码,从而消除上述2个问题呢,这时候我们就要引入.NET中的文本描述属性类DescriptionAttribute

使用DescriptionAttribute重构代码

其实.NET中已经提供了一个文本描述属性类DescriptionAttribute, 这个属性类的构造函数可以接收一段文字描述。

下面我们使用DescriptionAttribute来改造Level枚举类型。

	public enum Level
{
//Bad
[Description("Bad")]
B = -1, //Normal
[Description("Normal")]
N = 0, //Good
[Description("Good")]
G = 1, //Very Good
[Description("Very Good")]
VG = 2
}

这样我们上面提到的第二个问题就解决了,现在Level枚举类型的枚举值和显示值就都封装在了一起。

那么第一个问题该怎么解决呢?

这里我们可以针对Enum类型添加扩展方法,并使用反射读取当前枚举值所对应的显示值

	public static class EnumExtension
{
public static string ToDescription(this Enum val)
{
var type = val.GetType(); var memberInfo = type.GetMember(val.ToString()); var attributes = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes == null || attributes.Length != 1)
{
//如果没有定义描述,就把当前枚举值的对应名称返回
return val.ToString();
} return (attributes.Single() as DescriptionAttribute).Description;
}
}

由于Enum类型是所有枚举类型的基类型,所以所有的枚举类型都可以使用这个扩展方法。

总结

本篇博文中,我们讲解了如果如何.NET内置的文本描述属性类DescriptionAttribute来生成枚举值对应的文本,它不仅可以减少重复代码,还可以让整个枚举类型的内聚性更高。

[小技巧]C#中如何为枚举类型添加描述方法的更多相关文章

  1. Python中模拟enum枚举类型的5种方法分享

    这篇文章主要介绍了Python中模拟enum枚举类型的5种方法分享,本文直接给出实现代码,需要的朋友可以参考下   以下几种方法来模拟enum:(感觉方法一简单实用) 复制代码代码如下: # way1 ...

  2. Java中的Enum枚举类型总结

    废话不多说,直接上代码,该例子来源于:http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html public enum Planet { ...

  3. grep的用法,小技巧,模板中含有\t时:grep -P "^\t" file

    linux中grep和find的用法区别 本文章详细的介绍了关于在linux中的grep和find两个命令的用法介绍,以及后面总结了它们两年用法区别哦. 先我们来介绍一下关于grep用法和一些小注意事 ...

  4. 为枚举类型添加说明 zt

    enum Orientation { [DescriptionAttribute("东")] East, [DescriptionAttribute("南")] ...

  5. 小技巧:webpack中@的配置和用法

    好家伙, 当我们要各种两个文件去引用别的文件时,一般这么写 import msg from '../../msg.js' 那么如果文件藏得很深,'../'会变得很多,不美观,也不直观 所以我们又又又可 ...

  6. iOS开发小技巧 - label中的文字添加点击事件

    Label中的文字添加点击事件 GitHub地址:https://github.com/lyb5834/YBAttributeTextTapAction 以前老师讲过类似的功能,自己懒得回头看了,找了 ...

  7. iOS开发小技巧--iOS中设置applicationIconBadgeNumber遇到的问题

    iOS中设置applicationIconBadgeNumber 在iOS7中直接设置applicationIconBadgeNumber没有问题,但是在iOS8之后设置applicationIcon ...

  8. iOS开发小技巧--TableView中headerView的循环利用,以及自定义的headerView

    一.首先要搞清楚,tableView中有两种headerView,一个是tableHeaderView,另一个是headerView.前者就一个;后者根据session决定个数 headerView的 ...

  9. 小技巧 - CSS中:hover调试

    在调试CSS的时候,我一般使用Chrome的F12开发者工具,或者FireFox的FireBug直接在元素上面修改好Style后,再写入到CSS中.前几天遇到一个问题就是a:hover,鼠标一移开效果 ...

随机推荐

  1. Python+Selenium+PIL+Tesseract真正自动识别验证码进行一键登录

    Python 2.7 IDE Pycharm 5.0.3 Selenium:Selenium的介绍及使用,强烈推荐@ Eastmount的博客 PIL : Pillow-3.3.0-cp27-cp27 ...

  2. python 写日志

    简单配置 日志级别 级别 何时使用 DEBUG 详细信息,典型地调试问题时会感兴趣. INFO 证明事情按预期工作. WARNING 表明发生了一些意外,或者不久的将来会发生问题(如'磁盘满了').软 ...

  3. 映射内网ftp服务器到公网报错问题解决

    这两天公司测试环境有个需求要让合作方通过ftp推送数据,一般内网环境是不会对公网开放ftp服务的,但是因为是临时需求就帮着搭了ftp服务,并且做了公网映射.ftp服务搭好之后在内网访问正常,但是在公网 ...

  4. bzoj 2500 幸福的道路 树上直径+set

    首先明确:树上任意一点的最长路径一定是直径的某一端点. 所以先找出直径,求出最长路径,然后再求波动值<=m的最长区间 #include<cstdio> #include<cst ...

  5. BZOJ_1026_[SCOI2009]windy数_数位DP

    BZOJ_1026_[SCOI2009]windy数_数位DP 题意:windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之 ...

  6. XSS SQL CSRF

    XSS(Cross Site Script,跨站脚本攻击)是向网页中注入恶意脚本在用户浏览网页时在用户浏览器中执行恶意脚本的攻击方式.跨站脚本攻击分有两种形式:反射型攻击(诱使用户点击一个嵌入恶意脚本 ...

  7. Python 魔术方法笔记

    魔术方法总是被__包围, 如__init__ , __len__都是常见的魔术方法,这里主要写一下我遇到的一些魔术方法 setitem 对某个索引值赋值时 即可以进行赋值操作,如 def __seti ...

  8. 亲测可用,iptables实现NAT转发。

    环境 服务器A:192.168.1.7 服务器B: 192.168.1.160 需求 实现将本机(192.168.1.7:7410)端口流量转发给(192.168.1.160:9200). 1. 内核 ...

  9. 企业私有源代码上传github致入侵之大疆案判决了

    事件简单回顾: 1.2017年8月28日,大疆宣布“大疆威胁识别奖励计划”,最高3万美元: 2.然而在此之前,大疆农业事业部某员工将企业私有源代码上传到了github: 3.就职于大疆竞对公司Depa ...

  10. asp.net core系列 45 Web应用 模型绑定和验证

    一. 模型绑定 ASP.NET Core MVC 中的模型绑定,是将 HTTP 请求中的数据映射到action方法参数. 这些参数可能是简单类型的参数,如字符串.整数或浮点数,也可能是复杂类型的参数. ...