c# 怎樣簡(jiǎn)潔高效的實(shí)現(xiàn)多個(gè) Enum 自由轉(zhuǎn)換
一:背景
1. 講故事
前段時(shí)間和同事負(fù)責(zé)一個(gè)項(xiàng)目的兩個(gè)業(yè)務(wù)模塊,可能大家缺少溝通,導(dǎo)致本該定義一個(gè) Enum 的地方結(jié)果我倆各自定義了一個(gè),導(dǎo)致后面這兩個(gè) Enum 進(jìn)行對(duì)接就煩了,為了方便理解,也不想讓大家看這崴腳的英文拼寫,我就拿 銀行 舉例吧。
- A同事 定義的枚舉
public enum BankEnum { ICBC = 1, CMSB = 2, CMBC = 3 }
- B同事 定義的枚舉
public enum ChinaBankEnum { 中國(guó)民生銀行 = 1, 中國(guó)工商銀行 = 2, 中國(guó)招商銀行 = 3, }
這就很尬尷了,怎么將 ChinaBankEnum 轉(zhuǎn)成 BankEnum 呢? 為了尋求多快好省,本篇就聊聊這個(gè)問題。
二:尋找解決辦法
1. 手工匹配
本質(zhì)上就是找兩個(gè) Enum 的 mapping 關(guān)系,人肉匹配那是最簡(jiǎn)單粗暴的,代碼如下:
static BankEnum ConvertToEnum(ChinaBankEnum chinaBank) { switch (chinaBank) { case ChinaBankEnum.中國(guó)工商銀行: return BankEnum.ICBC; case ChinaBankEnum.中國(guó)民生銀行: return BankEnum.CMSB; case ChinaBankEnum.中國(guó)招商銀行: return BankEnum.CMBC; } return default(BankEnum); }
看的出來,這種寫法缺少靈活性,作為程序員肯定不能滿足于此,既然是找 mapping 關(guān)系,我相信很多朋友最早聽說 mapping 一詞是來源于 EntityFramework ,人家在處理 table 到 model 的 mapping 采用的是 Attribute,是不是這樣,靈感就在于此,我是不是也可以使用 Attribute 來標(biāo)記兩個(gè) Enum 的對(duì)應(yīng)關(guān)系呢???
2. 使用 Attribute
有了這個(gè)思路,就可以自定義一個(gè) Attribute,當(dāng)然比較懶的話,也可以用 Framework 自帶的 DescriptionAttribute
,代碼如下:
[AttributeUsage(AttributeTargets.All)] public class DescriptionAttribute : Attribute { public DescriptionAttribute(){} public DescriptionAttribute(string description){} }
接下來就可以把 Description 套在 BankEnum 上,如下代碼所示:
public enum BankEnum { [Description(nameof(ChinaBankEnum.中國(guó)工商銀行))] ICBC = 1, [Description(nameof(ChinaBankEnum.中國(guó)民生銀行))] CMSB = 2, [Description(nameof(ChinaBankEnum.中國(guó)招商銀行))] CMBC = 3 }
然后我可以通過反射拿到 Attribute 的值再去 ChinaBankEnum 中去找對(duì)應(yīng)的 key 即可,對(duì)不對(duì),為了方便理解,我封裝一個(gè) Enum 的擴(kuò)展方法,通過反射實(shí)現(xiàn) Enum 對(duì) Enum 的轉(zhuǎn)換,代碼如下:
/// <summary> /// 枚舉的擴(kuò)展方法 /// </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); } }
代碼邏輯還是比較簡(jiǎn)單的,接下來寫兩個(gè)例子測(cè)試下:
static void Main(string[] args) { ChinaBankEnum chinaBankEnum = ChinaBankEnum.中國(guó)工商銀行; ChinaBankEnum chinaBankEnum2 = ChinaBankEnum.中國(guó)招商銀行; var bankEnum = chinaBankEnum.ConvertTo<BankEnum>(); var bankEnum2 = chinaBankEnum2.ConvertTo<BankEnum>(); Console.WriteLine($"{chinaBankEnum} -> {bankEnum}\r\n{chinaBankEnum2} -> {bankEnum2}"); }
3. 對(duì) Parse 轉(zhuǎn)換的一些優(yōu)化
不知道大家在寫代碼的時(shí)候有沒有發(fā)現(xiàn)將 string 或者 int 轉(zhuǎn)成 Enum 的時(shí)候,寫出來的代碼是又臭又長(zhǎng),比如下面這樣:
var bankEnum = (ChinaBankEnum)Enum.Parse(typeof(ChinaBankEnum), "中國(guó)工商銀行");
又是 typeof 又是類型強(qiáng)轉(zhuǎn)換,而且強(qiáng)轉(zhuǎn)不過來的話還會(huì)拋異常,基于各種原因 framework 又新增了一個(gè) TryParse,如下圖所示:
看起來確實(shí)好多了,但還是覺得有點(diǎn)不爽,為了再順眼一些,我決定在 EnumExtension 中再封裝一個(gè) 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; } }
調(diào)用的時(shí)候就可以這么來: var bankEnum = "中國(guó)工商銀行".TryParse<ChinaBankEnum>();
,是不是就順眼多了哈。
三: 總結(jié)
哈,本篇就來自于項(xiàng)目開發(fā)中遇到的一個(gè)坑,相信很多朋友都會(huì)遇到類似的情況,遺憾的是默認(rèn)的 Enum 提供的功能太弱,大家可以根據(jù)自己的業(yè)務(wù)在 Enum 上擴(kuò)充更多實(shí)用的方法,如獲取所有的key,所有的value 等等,讓自己的代碼更加整潔,干凈,強(qiáng)大!
以上就是c# 怎樣簡(jiǎn)潔高效的實(shí)現(xiàn)多個(gè) Enum 自由轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于c# Enum 自由轉(zhuǎn)換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#實(shí)現(xiàn)圖表中鼠標(biāo)移動(dòng)并顯示數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)圖表中鼠標(biāo)移動(dòng)并顯示數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02C#中Convert.ToString和ToString的區(qū)別分析
這篇文章主要介紹了C#中Convert.ToString和ToString的區(qū)別,是C#初學(xué)者需要牢固掌握的技巧,需要的朋友可以參考下2014-08-08C#確保只有一個(gè)實(shí)例在運(yùn)行的方法
這篇文章主要介紹了C#確保只有一個(gè)實(shí)例在運(yùn)行的方法,涉及C#進(jìn)程操作的相關(guān)技巧,需要的朋友可以參考下2015-05-05C#實(shí)現(xiàn)BBcode轉(zhuǎn)為Markdown的方法
這篇文章主要給大家介紹了關(guān)于C#實(shí)現(xiàn)BBcode轉(zhuǎn)Markdown的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-02-02WPF+SkiaSharp實(shí)現(xiàn)自繪投籃小游戲
這篇文章主要介紹了如何利用WPF+SkiaSharp實(shí)現(xiàn)自繪投籃小游戲。此案例主要是針對(duì)光線投影法碰撞檢測(cè)功能的示例,順便做成了一個(gè)小游戲,很簡(jiǎn)單,但是,效果卻很不錯(cuò),感興趣的可以動(dòng)手嘗試一下2022-08-08