聲明:
本文內容出自:http://www.codeproject.com/useritems/DotNetEnumsNextLevel.asp
由於本人E文菜得實在離譜,對文章的“翻譯”①僅限於自娛自樂,文中用詞過於牽強而且漏洞百出,強烈建議讀者打開上面的鏈接閱讀原文。
-------------------------------------------------------------
導言
在這篇文章裏我將對.NET中的枚舉做進一步探索,本文不會含蓋枚舉的基本概念、語法或者使用方法(這些你可以通過MSDN得到詳細的信息),最大的限制是枚舉只能使用 Integer 數據類型。枚舉提供了 ToString() 方法的支持,但卻有限制(我會在文章後面詳細論述)。主要地,我希望能夠把我所列舉的枚舉元素不僅僅關聯到整數數據,我將通過反射(Reflection)和屬性(Attributes)跟使用盡量簡單的例子來說明如何達到這一目標。
在 Enum 中使用 ToString()
我們先來創建一個簡單的枚舉。。。
{
RegularEmployee,
StoreManager,
ChainStoreManager,
DepartmentManager,
Supervisor
}
我們可以通過 ToString() 方法簡單地獲取到下列信息
Console.WriteLine(employee.ToString());
Console.WriteLine(EmployeeType.ChainStoreManager.ToString());
/**//*
輸出結果:
ChainStoreManager
ChainStoreManager
*/
但我們如何才能獲取到的結果類似“Chain Store Manager”包括空格呢?我們不能去創建一個包含空格的枚舉成員,否則你的代碼將不能編譯通過,事實上我們有很多方案可以解決這個問題。
1、在枚舉成員和字符串之間創建一個映射(可以使用數組或哈希表)
2、將枚舉成員 ToString() 的結果作爲爲鍵指定到資源文件
3、使用反射。。。。(我將在下面講到)
在枚舉中使用屬性
我將使用屬性來達到一個字符串關聯到枚舉成員的目的,下面通過一個簡單的例子來說明這是如何做到的。
{
private string m_strDescription;
public EnumDescriptionAttribute(string strPrinterName)
{
m_strDescription = strPrinterName;
}
public string Description
{
get { return m_strDescription; }
}
}
EnumDescriptionAttribute 類繼承自 Attribute,它包含一個類型爲String的屬性Description,下面將該屬性關聯到枚舉 EmployeeType 的所有成員上。
{
[EnumDescription("Regular Employee")]
RegularEmploye,
[EnumDescription("Store Manager")]
StoreManager,
[EnumDescription("Chain Store Manager")]
ChainStoreManager,
[EnumDescription("Department Manager")]
DepartmentManager,
[EnumDescription("On Floor Supervisor")]
Supervisor
}
從枚舉獲取到屬性的值
爲了獲取到屬性的值,我必須使用到反射,下是是一個簡單的例子:
EmployeeType employee = EmployeeType.ChainStoreManager;
// get the field informaiton
FieldInfo fieldInfo = employee.GetType().GetField("ChainStoreManager");
// get the attributes for the enum field
object[] attribArray = fieldInfo.GetCustomAttributes(false);
// cast the one and only attribute to EnumDescriptionAttribute
EnumDescriptionAttribute attrib = (EnumDescriptionAttribute)attribArray[0];
// write the description
console.WriteLine("Description: {0}", attrib.Description);
/**//*
輸入結果:
Chain Store Manager
*/
其中最重點的一行代碼:FieldInfo fieldInfo = employee.GetType().GetField("ChainStoreManager"); 我們注意硬編碼到裏面的枚舉成員名稱ChainStoreManager實際上可以通過 ToString() 方法來代替。
一個獲取描述信息的通用方法
其中使用了 ToString() 方法
{
System.Reflection.FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
{
return String.Empty;
}
else
{
EnumDescriptionAttribute attrib = attribArray[0] as EnumDescriptionAttribute;
return attrib.Description;
}
}
讓枚舉成員關聯到更多的數據類型
到目前爲止我們僅僅在我們的枚舉成員中添加了描述信息,不過我們是完全可以讓我們的枚舉關聯到任何一種數據類型的,我交將創建一個新的枚舉來展示我的想法(這跟前面的做法一樣)。
{
StoreManager,
ChainManager,
Superivor
}
而且我還得創建一個 EnumDescription 的派生類 ManagerAttribute,跟提供兩個價格信息(最高和最低薪水值)
{
private int m_intMinSalary;
private int m_intMaxSalary;
public ManagerAttribute(string strDescription, int intMinSalary, int intMaxSalary)
: base(strDescription)
{
m_intMinSalary = intMinSalary;
m_intMaxSalary = intMaxSalary;
}
public ManagerAttribute(string strDescription)
: base(strDescription)
{
}
public int MinSalary
{
get { return m_intMinSalary; }
set { m_intMinSalary = value; }
}
public int MaxSalary
{
get { return m_intMaxSalary; }
set { m_intMaxSalary = value; }
}
}
現在我將 ManagerAttribute 關聯到所有枚舉成員上,爲了讓代碼的可讀性更強,給 ManagerAttributes 的所有屬性都附了值。
{
[Manager("Store Manager", MinSalary=40000, MaxSalary=100000)]
StoreManager,
[Manager("Chain Manager", MinSalary=50000, MaxSalary=110000)]
ChainManager,
[Manager("Store Supervisor", MinSalary=30000, MaxSalary=50000)]
Superivor
}
下一步是改進獲取 EnumDescriptionAttribute 屬性值的通用方法,讓它支持所有數據類型,使用C# 2.0 中的泛型(Generics)很容易辦到
{
// get field informaiton for our enum element
FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
// get all the attributes associated with our enum
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
return default(T);
else
{
// cast the attribute and return it
T attrib = (T)attribArray[0];
if (attrib != null)
return attrib;
else
return default(T);
}
}
工具方法
到目前爲止我們已經寫了兩個工具類,一個是簡單地實現了從枚舉中獲取描述信息,另一個繼承自 EnumDescriptionAttribute 的更通用的方法可以獲取任何數據類型的屬性值,你可以把它們添加到你的枚舉工具類(如:EnumHelper)中去,這裏我還是簡單地把它放在 EnumDescriptionAttribute 中。
{
private string m_strDescription;
public EnumDescriptionAttribute(string strEnumDescription)
{
m_strDescription = strEnumDescription;
}
public string Description { get { return m_strDescription; } }
public static string GetEnumDescription(Enum enumObj)
{
System.Reflection.FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
return String.Empty;
else