用列舉(Enum)來當作類型的使用是很好的選擇
但在某些情境下,需要使用中文顯示類型內容,
這時候該怎麼辦呢?
在某些情境或需求下,會需要用到類型來區分不同條件或情境
一開始最直接的方法就是用字串的方式設定,
然而, 這種方式會有些缺點存在
- 非強型別, 有打錯字的風險, 編譯時期無法發現錯誤, 容易造成除錯上的不便
- 每次需要用到時,都需要手刻一遍,那怕用複製貼上,也是不方便
- 假如有類型命名有誤需修改時,容易有漏改的問題
這時候列舉(Enum)的好處就顯示出來了,
強型別且有intellisense提示,重新命名時可用重構的功能將所有參考的地方一起修改
上述的缺點都可得到改善
通常列舉中的類型命名在程式中溝通不會有什麼問題,
但在某些情境下,需要使用中文顯示類型內容,
頓時覺得頭大了起來
根據微軟MSDN的描述 『enum 的核准型別為 byte、sbyte、short、ushort、int、uint、long 或 ulong。』,根本就沒辦法接受string的型別,難道要將列舉的類型直接命名成中文?
以C#對中文命名支援,確實可以解決問題
但不建議使用(除非Code只有你一個人在寫且你自己可以忍受的話XD)
其實小魯有想到一種變通的方法,就是建立只有唯獨屬性的靜態Class
如此作法也確實擁有強型別的好處,但事情真的有那麼簡單嗎?
假如有一天,小明接到一個任務(可憐的小明):『現在有取得書籍類別清單的需求,加一下』,
非原作的小明發現的有一個叫做BookType的class,在未了解class原意下將method加到class中
程式可以正常運作且需求也達成,但架構卻被破壞
用class的方式無法阻止其他有心人士的加工
容易導致class失去原來用意
後來在網路上發現一種作法
就是欄位加上Description Attribute
在利用反射的方式取得Attribute的設定
做法如下:
建立列舉(Enum)
public enum BookTypeEnum
{
/// <summary>
/// 漫畫書
/// </summary>
[Description("漫畫書")]
ComicBook = 0,
/// <summary>
/// 參考書
/// </summary>
[Description("參考書")]
ReferenceBook = 1,
/// <summary>
/// 電子書
/// </summary>
[Description("電子書")]
eBook = 2
}
建立取得列舉(Enum)描述的方法
static string GetDescription(string value)
{
Type type = typeof(BookTypeEnum);
var name = Enum.GetNames(type)
.Where(f => f.Equals(value, StringComparison.CurrentCultureIgnoreCase))
.Select(d => d)
.FirstOrDefault();
//// 找無相對應的列舉
if (name == null)
{
return string.Empty;
}
//// 利用反射找出相對應的欄位
var field = type.GetField(name);
//// 取得欄位設定DescriptionAttribute的值
var customAttribute = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
//// 無設定Description Attribute, 回傳Enum欄位名稱
if (customAttribute == null || customAttribute.Length == 0)
{
return name;
}
//// 回傳Description Attribute的設定
return ((DescriptionAttribute)customAttribute[0]).Description;
}
緊接著在需要取得中文描述的時候呼叫method
static void Main(string[] args)
{
var bookType = GetDescription(BookTypeEnum.ComicBook.ToString());
var result = string.Format("BookTypeEnum Description: {0}", bookType);
Console.Write(result);
Console.Read();
}
運行後結果如下:
如此就能享受到列舉(Enum)的好處^_^ Y
參考來源:
https://msdn.microsoft.com/zh-tw/library/sbbt4032.aspx
http://www.extensionmethod.net/csharp/enum/getenumdescription
註: 此篇文章有觀念錯誤之處,歡迎各位大大不吝指教