探討attribute
一、前言
相信很多程式開發人員都有碰過,在專案的某些類別(class)或是列舉(enum)中都有像下圖一樣的寫法
這種寫法像是metadata,也就是程式的「資料標記」,至於這種寫法的用途很廣,有空再根據自已所知的再舉例
這篇只介紹如何取得Description的內容,因為自已也是在摸索這種寫法的功用,後續會把自已的心得一個一個寫下來
圖1.1
二、Description類別
Description其實就是DescriptionAttribute,繼承Attribute(圖2.1),所以Description很多特性都是來自已attribute,簡單來說就是Attribute的擴充
而當你使用像下面的code,其實就是將值指給DescriptionAttribute中的Description屬性
[Description("學生姓名")]
圖2.1
三、取得Desctipon的內容
這邊以class跟enum為例
1.class
(1)先撰寫一個student的class,並加上class、屬性、方法的description(圖3.1)
圖3.1
(2)分別取得class、屬性、方法的Description
要取得這三者的Description,首先要了解type、PropertyInfo、MethodInfo,這三個類別都有一個GetCustomAttributes的function,就是透過它來取得
a.取得class的Description-->用type的GetCustomAttributes
//取得目標物件的type
Type oType = typeof(Student);
//取得類別的description
object[] classAttrs = oType.GetCustomAttributes(true);
foreach (var attr in classAttrs)
{
DescriptionAttribute da = attr as DescriptionAttribute;
if (da != null)
{
Console.WriteLine(da.Description);
}
}
b.取得屬性的Description-->用PropertyInfo的GetCustomAttributes
//取得屬性的description
PropertyInfo[] props = oType.GetProperties();
foreach (var prop in props)
{
object[] attrs = prop.GetCustomAttributes(true);
foreach (var attr in attrs)
{
DescriptionAttribute da = attr as DescriptionAttribute;
if (da != null)
{
Console.WriteLine(da.Description);
}
}
}
c.取得方法的Description-->用MethodInfo的GetCustomAttributes
//取得方法的description
MethodInfo[] oMethodInfos = oType.GetMethods();
foreach (var method in oMethodInfos)
{
object[] methodAttrs = method.GetCustomAttributes(true);
foreach (var attr in methodAttrs)
{
DescriptionAttribute da = attr as DescriptionAttribute;
if (da != null)
{
Console.WriteLine(da.Description);
}
}
}
2.enum
(1)先撰寫一個ClassRoom的enum,並加上enum跟其成員的Description(圖3.2)
圖3.2
(2)分別取得enum跟成員的Description
要取得這兩者的Description,首先要了解Type跟FieldInfo,這兩個類別都有一個GetCustomAttributes的function,就是透過它來取得
a.取得enum的Description-->用type的GetCustomAttributes
//取得enum的description
var type = typeof(ClassRoom);
if (!type.IsEnum) throw new InvalidOperationException();
object[] enumTypeDesc = type.GetCustomAttributes(true);
foreach (var desc in enumTypeDesc)
{
if (desc.GetType() == typeof(DescriptionAttribute))
{
var transDesc = (DescriptionAttribute)desc;
System.Console.WriteLine(transDesc.Description);
}
}
b.取得成員的Description-->用FieldInfo的GetCustomAttributes
//取得成員(member)的description
foreach (var field in type.GetFields())
{
object[] enumMemberDesc = field.GetCustomAttributes(true);
foreach (var desc in enumMemberDesc)
{
if (desc.GetType() == typeof(DescriptionAttribute))
{
var transDesc = (DescriptionAttribute)desc;
System.Console.WriteLine(transDesc.Description);
}
}
}
三、總結
其實這篇的程式重點應該在於type、PropertyInfo、MethodInfo、FieldInfo,依照名稱可以整理成下表,比較需要注意的大概就是
GetCustomAttributes(true),設true會跟該類別的繼承有關,不過目前不會有繼承的或是被繼承的類別,所以true或false不會有影響
後續再研究該參數的用意
MSDN:type
type | 類別 | |
PropertyInfo | 屬性 | 透過type的GetProperties() |
MethodInfo | 方法 | 透過type的GetMethods() |
FieldInfo | 欄位 | 透過type的GetFields() |