首先需要從內部了解一下枚舉(Enumeration),相信許多人已經知道了,當我們聲明一個這樣的枚舉類型:
enumMyEnum
{
AAA, BBB, CCC
}
背后的IL是這樣的:
.classprivate auto ansi sealed MyEnum
extends [mscorlib]System.Enum
{
.field publicstatic literal valuetype Mgen.MyEnum AAA = int32(0)
.field publicstatic literal valuetype Mgen.MyEnum BBB = int32(1)
.field publicstatic literal valuetype Mgen.MyEnum CCC = int32(2)
.field public specialname rtspecialname int32 value__
}
那沒,其實枚舉中的常量都是靜態的字段。而枚舉對象的值會保存在非靜態的特殊字段value__中。
因此,用反射來獲取名稱其實就是獲取類型的所有靜態字段就可以了,如下代碼:
var fields =typeof(MyEnum).GetFields(BindingFlags.Static |BindingFlags.Public);
foreach (var fi in fields)
Console.WriteLine(fi.Name);
輸出:
AAA
BBB
CCC
對於值得獲取也很簡單,通過反射得到的代表靜態字段的FieldInfo來獲取值就可以,並且獲取的值仍屬於枚舉類型的。如果想獲取枚舉背后的類型,仍需要Enum.GetUnderlyingType方法,如下代碼:
var fields =typeof(MyEnum).GetFields(BindingFlags.Static |BindingFlags.Public);
foreach (var fi in fields)
{
var value = fi.GetValue(null);
Console.WriteLine("值:{0} 類型:{1} 枚舉背后類型:{2}",
value, value.GetType(), Enum.GetUnderlyingType(value.GetType()));
}
輸出:
值:AAA 類型:Mgen.MyEnum 枚舉背后類型:System.Int32
值:BBB 類型:Mgen.MyEnum 枚舉背后類型:System.Int32
值:CCC 類型:Mgen.MyEnum 枚舉背后類型:System.Int32
最后獲取特性,通過MemberInfo類型的GetCustomAttributes方法或者Attribute類型的靜態方法都可以,比如在枚舉值上加一個特性:
enumMyEnum
{
AAA, BBB,
[Obsolete]
CCC
}
代碼:
var fields =typeof(MyEnum).GetFields(BindingFlags.Static |BindingFlags.Public);
foreach (var fi in fields)
Console.WriteLine(Attribute.GetCustomAttribute(fi, typeof(ObsoleteAttribute), false) !=null);
輸出:
False
False
True
作者:Mgen
出處:www.cnblogs.com/mgen
其他參考頁面:我的軟件和工程,博客導讀。