背景 前幾天有同事問到我一個簡單的功能, 就是當你使用枚舉時如何給每個一元素增加描述字元串並且可以很容易的讀取出來. 比如有一個枚舉類型是列出對一個問題給出的選項(例如: 同意?不同意?中立?): public enum AssessmentAnswer { Strongly_Disagree =
背景
前幾天有同事問到我一個簡單的功能, 就是當你使用枚舉時如何給每個一元素增加描述字元串並且可以很容易的讀取出來.
比如有一個枚舉類型是列出對一個問題給出的選項(例如: 同意?不同意?中立?):
public enum AssessmentAnswer
{
Strongly_Disagree = 1,
Disagree = 2,
Neutral = 3,
Agree = 4,
Strongly_Agree = 5
}
當選擇不同的答案時, 希望得到一些描述性的語句比方說: 1. "強烈的反對" 2. "反對" 3. "持中立觀點" 4. "同意" 5. "完全的同意" 當然你可以建立一個資料庫表格,存放這些信息, 但是我想起幾年前,我在網上下載一個 EnumDescription 源碼(忘記了是在哪裡下載的), 就可以實現這一功能. 讓我們一起來看看是怎麼樣用 Extension 做到的:
實現
首先定義一個EnumDescription 類:public class EnumDescription : Attribute
{
public string Text
{
get { return _text; }
} private string _text;
public EnumDescription(string text)
{
_text = text;
}
}
註意它的父類是Attribute, 因為我們希望將描述的語句作為每一個對應元素的特性. 然後新建一個文件,命名EnumExtensions.cs
public static class EnumExtensions
{
public static string ToDescription(this Enum enumeration)
{
Type type = enumeration.GetType();
MemberInfo[] memInfo = type.GetMember(enumeration.ToString());
if (null != memInfo && memInfo.Length > 0)
{
object[] attrs = memInfo[0].GetCustomAttributes(typeof(EnumDescription), false);
if (null != attrs && attrs.Length > 0)
return ((EnumDescription)attrs[0]).Text;
}
return enumeration.ToString();
}
}
在這裡我們定義了一個擴展函數ToDescription, 就像所有的擴展函數一樣,它的參數是類似(this …),
這個函數首先用GetType 得到了當前枚舉的類型, 然後藉助 GetMember按照元素的名字(值), 得到這個特定的元素, 最後用GetCustomAttributes 得到描述的內容.
這個擴展函數實現後,我們可以修改枚舉的定義,加入描述:
public enum AssessmentAnswer
{
[EnumDescription("強烈的反對")]
Strongly_Disagree = 1,
[EnumDescription("反對")]
Disagree = 2,
Neutral = 3,
Agree = 4,
[EnumDescription("完全的同意")]
Strongly_Agree = 5
}
當要獲取描述語句時, 你可以輕鬆的調用ToDescription :
//返回 "強烈的反對"
AssessmentAnswer.Strongly_Disagree.ToDescription()
註意, 如果沒有給元素加入特性, 你仍舊可以使用ToDescription, 可以參考上面的代碼看看是為什麼.
//返回 “Disagree”
AssessmentAnswer.Disagree.ToDescription()
總結
擴展方法作為特殊的靜態方法使您能夠向現有類型“添加”方法,而無需創建新的派生類型、重新編譯或以其他方式修改原始類型。
對於用 C# 和 Visual Basic 編寫的客戶端代碼,調用擴展方法與調用在類型中實際定義的方法之間沒有明顯的差異。
給初學者的話: 一旦當你實現擴展方法後, 你只需要複製dll 添加文件命名空間; 或者複製cs文件到你的項目中, 就可以使用這些方法, 但是建議除非你有充分的理由才實現擴展方法。
很多我們要用到的擴展方法都可以在網上得到, 所以一般在寫自己的擴展前請先搜索一下.