技术债! 怎样简洁高效的实现多个 Enum 自由转换

一:背景

1. 讲故事

前段时间和同事负责一个项目的两个业务模块,可能大家缺少沟通,导致本该定义一个 Enum 的地方结果我俩各自定义了一个,导致后面这两个 Enum 进行对接就烦了,为了方便理解,也不想让大家看这崴脚的英文拼写,我就拿 银行 举例吧。

  • A同事 定义的枚举

public enum BankEnum{ICBC = 1,CMSB = 2,CMBC = 3}
  • B同事 定义的枚举

public enum ChinaBankEnum{中国民生银行 = 1,中国工商银行 = 2,中国招商银行 = 3,}

这就很尬尴了,怎么将 ChinaBankEnum 转成 BankEnum 呢?为了寻求多快好省,本篇就聊聊这个问题。

二:寻找解决办法

1. 手工匹配

本质上就是找两个 Enum 的 mapping 关系,人肉匹配那是最简单粗暴的,代码如下:

static BankEnum ConvertToEnum(ChinaBankEnum chinaBank){switch (chinaBank){case ChinaBankEnum.中国工商银行: return BankEnum.ICBC;case ChinaBankEnum.中国民生银行: return BankEnum.CMSB;case ChinaBankEnum.中国招商银行: return BankEnum.CMBC;}return default(BankEnum);}

看的出来,这种写法缺少灵活性,作为程序员肯定不能满足于此,既然是找 mapping 关系,我相信很多朋友最早听说 mapping 一词是来源于 EntityFramework ,人家在处理 table 到 model 的 mapping 采用的是 Attribute,是不是这样,灵感就在于此,我是不是也可以使用 Attribute 来标记两个 Enum 的对应关系呢???

2. 使用 Attribute

有了这个思路,就可以自定义一个 Attribute,当然比较懒的话,也可以用 Framework 自带的 DescriptionAttribute,代码如下:

[AttributeUsage(AttributeTargets.All)]public class DescriptionAttribute : Attribute{public DescriptionAttribute(){}public DescriptionAttribute(string description){}}

接下来就可以把 Description 套在 BankEnum 上,如下代码所示:

public enum BankEnum{[Description(nameof(ChinaBankEnum.中国工商银行))]ICBC = 1,[Description(nameof(ChinaBankEnum.中国民生银行))]CMSB = 2,[Description(nameof(ChinaBankEnum.中国招商银行))]CMBC = 3}

然后我可以通过反射拿到 Attribute 的值再去 ChinaBankEnum 中去找对应的 key 即可,对不对,为了方便理解,我封装一个 Enum 的扩展方法,通过反射实现 Enum 对 Enum 的转换,代码如下:

/// <summary>/// 枚举的扩展方法/// </summary>public static class EnumExtension{public static Target ConvertTo<Target>(this Enum enumValue) where Target : Enum{var key = Enum.GetName(enumValue.GetType(), enumValue);var fields = typeof(Target).GetFields();foreach (var field in fields){var attribute = field.GetCustomAttribute<DescriptionAttribute>();if (attribute == null) continue;if (key == attribute.Description){var obj = (Target)field.GetValue(typeof(Target));return obj;}}return default(Target);}}

代码逻辑还是比较简单的,接下来写两个例子测试下:

static void Main(string[] args){ChinaBankEnum chinaBankEnum = ChinaBankEnum.中国工商银行;ChinaBankEnum chinaBankEnum2 = ChinaBankEnum.中国招商银行;var bankEnum = chinaBankEnum.ConvertTo<BankEnum>();var bankEnum2 = chinaBankEnum2.ConvertTo<BankEnum>();Console.WriteLine($"{chinaBankEnum} -> {bankEnum}\r\n{chinaBankEnum2} -> {bankEnum2}");}

3. 对 Parse 转换的一些优化

不知道大家在写代码的时候有没有发现将 string 或者 int 转成 Enum 的时候,写出来的代码是又臭又长,比如下面这样:

var bankEnum = (ChinaBankEnum)Enum.Parse(typeof(ChinaBankEnum), "中国工商银行");

又是 typeof 又是类型强转换,而且强转不过来的话还会抛异常,基于各种原因 framework 又新增了一个 TryParse,如下图所示:

看起来确实好多了,但还是觉得有点不爽,为了再顺眼一些,我决定在 EnumExtension 中再封装一个 TryParse 方法,如下代码所示:

public static class EnumExtension{public static T TryParse<T>(this string value) where T : struct{var isSucc = Enum.TryParse<T>(value, out var result);if (!isSucc) return default(T);return result;}}

调用的时候就可以这么来: var bankEnum = "中国工商银行".TryParse<ChinaBankEnum>();,是不是就顺眼多了哈。

三:总结

哈,本篇就来自于项目开发中遇到的一个坑,相信很多朋友都会遇到类似的情况,遗憾的是默认的 Enum 提供的功能太弱,大家可以根据自己的业务在 Enum 上扩充更多实用的方法,如获取所有的key,所有的value 等等,让自己的代码更加整洁,干净,强大!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分享套接字数据包序列化与反序列化方法

分享套接字数据包序列化与反序列化方法“简单说一下&#xff0c;本文不涉及Socket的连接、数据接收&#xff0c;只是对数据包(byte[])的序列化和反序列化方法的封装介绍。本文目录本文背景一般操作本文操作总结1.本文背景经常做C/S&#xff0c;客户端与服务端通信基本是TCP/UDP…

leetcode22. 括号生成(回溯)

一:题目 二:上码 class Solution {public List<String> generateParenthesis(int n) {List<String> ans new ArrayList<>();def(ans,new StringBuilder(),n,n);return ans;}/**left:左边还可以用的括号数量right:右边还可以用的括号数量*/public void def(…

leetcode31. 下一个排列

一:题目 二:上码 class Solution {/**规律: 从后往前找到那个比其小的数进行交换 然后 在小的数后面的数都进行排序12345 --> 1235412354 --> 12453 --> 12435*/public void nextPermutation(int[] nums) {int len nums.length;for (int i len - 1; i > 0; i--)…

回顾 | 进击吧! Blazor !第三期 信息交互

Blazor 是一个 Web UI 框架&#xff0c;可通过 WebAssembly 在任意浏览器中运行 .Net 。Blazor 旨在简化快速的单页面 .Net 浏览器应用的构建过程&#xff0c;它虽然使用了诸如 CSS 和 HTML 之类的 Web 技术&#xff0c;但它使用 C&#xff03;语言和 Razor 语法代替 JavaScrip…

回顾 | 进击吧! Blazor !第四期 组件开发

Blazor 是一个 Web UI 框架&#xff0c;可通过 WebAssembly 在任意浏览器中运行 .Net 。Blazor 旨在简化快速的单页面 .Net 浏览器应用的构建过程&#xff0c;它虽然使用了诸如 CSS 和 HTML 之类的 Web 技术&#xff0c;但它使用 C&#xff03;语言和 Razor 语法代替 JavaScrip…

面试官:请问一条select的语句的执行会发生什么?

文章目录前言:一:执行一条select的概览二:具体流程1:连接器(1):步骤(2):浅浅来一下细节2:查询缓存(1):mysql5.8之前的幸福时光(2):mysql5.8之后的悲惨结果3:解析器(解析sql)(1):词法解析(2):语法解析4.执行sql(1):预处理阶段(2):优化阶段(3):执行器(1):概述(2):三种方式a:主键索…

跟我一起学.NetCore之MVC过滤器,这篇看完走路可以仰着头走

前言MVC过滤器在之前Asp.Net的时候就已经广泛使用啦&#xff0c;不管是面试还是工作&#xff0c;总有一个考点或是需求涉及到&#xff0c;可以毫不疑问的说&#xff0c;这个技术点是非常重要的&#xff1b; 在之前参与的面试中&#xff0c;得知很多小伙伴只知道有一两个过滤器&…

彭博社:中企游说政府否决英伟达收购Arm

9月14日&#xff0c;英伟达与软银宣布达成最终协议&#xff0c;英伟达将以400亿美元的价格从软银收购ARM。在台积电明确于9月15日后不再向HW的ARM提供代工服务之后&#xff0c;一家美国公司又将ARM收入囊中&#xff0c;这使国产ARM CPU在设计和制造环节都存在巨大风险&#xff…

Explain各个字段的含义

文章目录[TOC]1:expanin的结果示例2:各个字段的含义(1):id(2):select_type(3):table(4):type&#xff08;重要 我们利用索引查找出来的记录显示&#xff09;(5): possible_keys(6):key(7):key_len(8):ref(8):rows(重要)(9):extra1:expanin的结果示例 mysql> explain select…

asp.net core监控—引入Prometheus(三)

上一篇博文中说到Prometheus有四种指标类型&#xff1a;Counter&#xff08;计数器&#xff09;、Gauge&#xff08;仪表盘&#xff09;、Histogram&#xff08;直方图&#xff09;、Summary&#xff08;摘要&#xff09;&#xff0c;并且我们做了一个Counter的Demo&#xff0c…

秋招日常(一天三封感谢信)

就离谱 上午收到两封 搞得复习贼没心态 下午打完球回来一看手机又收到一封 这个有点伤 自己测评完 笔试 笔试完 约面 技术面过了 hr又面 面完说等消息 我寻思hr面能有啥可挂的 就离谱 一想到自己经过那么多轮 还是挂了 就难受 什么鬼 求求了 给个offer吧 要不我快成了天天向下的…

asp.net core监控—引入Prometheus(一)

Prometheus是CNCF毕业的第二个项目&#xff0c;算是明星产品&#xff08;可自行了解Prometheus的功能&#xff09;&#xff0c;asp.net core当然不能错过与之配套使用。在.net中是通过prometheus.net【https://github.com/prometheus-net/prometheus-net】引入的。上图是用Prom…

1024福利 | .NET社区联合清华大学出版社送好书来啦!

话不多说&#xff0c;直入主题。.NET社区各大公众号联合清华大学出版社为粉丝送上1024的福利&#xff0c;还请诸位笑纳&#xff01;&#xff01;&#xff01;有哪些书呢&#xff1f;.NET并发编程实战 作者&#xff1a;[美] 里卡尔多特雷尔&#xff08;Riccardo Terrell&#xf…

asp.net core监控—引入Prometheus(二)

上一篇博文中&#xff0c;说明了怎么引进Prometheus到asp.net core项目中&#xff0c;因为是Demo&#xff0c;所以Prometheus和Grafana都是windows版本&#xff0c;本地执行的&#xff0c;生产环境上这些服务可以根据的公司的架构&#xff0c;放到适合的环境内&#xff0c;现在…

ASP.NET Core Blazor Webassembly 之 渐进式应用(PWA)

Blazor支持渐进式应用开发也就是PWA。使用PWA模式可以使得web应用有原生应用般的体验。什么是PWAPWA应用是指那些使用指定技术和标准模式来开发的web应用&#xff0c;这将同时赋予它们web应用和原生应用的特性。例如&#xff0c;web应用更加易于发现——相比于安装应用&#xf…

TCP三次握手(详解)

一&#xff1a;引出 客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP connection的东西&#xff1b;由于TCP不存在连接的概念&#xff0c;只存在请求和响应&#xff0c;请求和响应都是数据包&#xff0c;它们之间都是经过由TCP创建的一个从客户端发起&#xf…

进击吧! Blazor !第五期 安全

Blazor 是一个 Web UI 框架&#xff0c;可通过 WebAssembly 在任意浏览器中运行 .Net 。Blazor 旨在简化快速的单页面 .Net 浏览器应用的构建过程&#xff0c;它虽然使用了诸如 CSS 和 HTML 之类的 Web 技术&#xff0c;但它使用 C&#xff03;语言和 Razor 语法代替 JavaScrip…

有一种无耻叫 “我是为你着想”

这是头哥侃码的第221篇原创十一之后&#xff0c;我的状态一直不好&#xff0c;总感觉胸口有东西堵着&#xff0c;时不时还会觉得呼吸困难。上周末&#xff0c;我咨询了几位有医学背景的朋友&#xff0c;有说是因为季节转换而造成的身体不适&#xff0c;不用在意&#xff0c;但也…

asp.net core监控—引入Prometheus(四)

上一篇博文中说到Prometheus有四种指标类型&#xff1a;Counter&#xff08;计数器&#xff09;、Gauge&#xff08;仪表盘&#xff09;、Histogram&#xff08;直方图&#xff09;、Summary&#xff08;摘要&#xff09;&#xff0c;并且我们做了一个Counter的Demo&#xff0c…