我們在上一篇「
Visual Basic - Reflection, 反映教學筆記(4) 取得型別的4種方法」中,在 Object 取得型別裡,給了一段不算短的程式碼,主要是顯示別型相關訊息。這一篇主要解釋那一段程式碼。此副程式的主要進入點為 ShowTypeAttributes()。
ShowTypeAttributes 副程式
04 | Sub ShowTypeAttributes() |
05 | Dim type As Type = GetType ( String ) |
07 | GetTypeAttribute(type) |
09 | ShowCustomAttribute(type) |
這裡很簡單,只是取得型別後,我想顯示一些型別的屬性、方法。我把這些方法另外再分為三個小副程式。
GetTypeAttribute 副程式
05 | Sub GetTypeAttribute(type As Type) |
06 | Console.WriteLine( "型別的屬性" ) |
07 | Console.WriteLine( "Assembly : {0}" , type. Assembly ) |
08 | Console.WriteLine( "AQN : {0}" , type.AssemblyQualifiedName) |
09 | Console.WriteLine( "Attributes: {0}" , type.Attributes) |
10 | Console.WriteLine( "BaseType: {0}" , type.BaseType) |
11 | Console.WriteLine( "FullName: {0}" , type.FullName) |
12 | Console.WriteLine( "HasElementType: {0}" , type.HasElementType) |
13 | Console.WriteLine( "IsAbstract: {0}" , type.IsAbstract) |
14 | Console.WriteLine( "IsByRef: {0}" , type.IsByRef) |
15 | Console.WriteLine( "IsClass: {0}" , type.IsClass) |
16 | Console.WriteLine( "IsEnum: {0}" , type.IsEnum) |
17 | Console.WriteLine( "IsGenericType: {0}" , type.IsGenericType) |
18 | Console.WriteLine( "IsInterface: {0}" , type.IsInterface) |
19 | Console.WriteLine( "IsMarshalByRef: {0}" , type.IsMarshalByRef) |
20 | Console.WriteLine( "IsNotPublic: {0}" , type.IsNotPublic) |
21 | Console.WriteLine( "IsPrimitive: {0}" , type.IsPrimitive) |
22 | Console.WriteLine( "IsPublic: {0}" , type.IsPublic) |
23 | Console.WriteLine( "IsSealed: {0}" , type.IsSealed) |
24 | Console.WriteLine( "IsValueType: {0}" , type.IsValueType) |
25 | Console.WriteLine( "IsVisible: {0}" , type.IsVisible) |
26 | Console.WriteLine( "Module: {0}" , type. Module ) |
27 | Console.WriteLine( "Name: {0}" , type.Name) |
28 | Console.WriteLine( "Namespace: {0}" , type. Namespace ) |
我們列出前一篇文章裡所提到的 Isxxx 屬性,這一類 Isxxx 都是回傳 Boolean 值,我建議打開 MSDN 裡的
System.Type 屬性對照著看,會比較清楚。
ShowCustomAttribute 副程式
05 | Sub ShowCustomAttribute(type As Type) |
06 | Console.WriteLine( "取得類別屬性:" ) |
07 | For Each attr As Attribute In type.GetCustomAttributes( True ) |
08 | Console.WriteLine( " {0}" , attr. GetType .Name) |
這裡注意我們使用的 type.
GetCustomAttributes(True) 必須傳入一個 Boolean 值,true 表示要搜尋這個成員的
繼承鏈結以尋找屬性,否則為 false。
對於屬性和事件來說,會忽略這個參數。若要搜尋屬性 (Property) 和事件之屬性 (Attribute) 繼承鏈結,請使用
Attribute.GetCustomAttributes 方法的適當多載。
ShowTypeGetxxx 副程式
這裡就精彩了。
ShowTypeGetxxx 又是另一個進入點,然後在裡面分別呼叫其他 7 支副程式,顯示此型別的屬性、巢狀型別、成員、建構子、事件、欄位、方法。
001 | #Region "顯示型別相關 Getxxx 方法" |
007 | Sub ShowTypeGetxxx(type As Type) |
009 | ShowGetProperties(type) |
011 | ShowGetNestedTypes(type) |
015 | ShowGetConstructors(type) |
028 | Private Sub ShowGetProperties(type As Type) |
029 | Console.WriteLine( "取得型別Properties" ) |
030 | For Each pi As PropertyInfo In type.GetProperties |
031 | Console.WriteLine( "{0}" , pi.Name) |
041 | Private Sub ShowGetNestedTypes(type As Type) |
042 | Console.WriteLine( "取得型別NestedTypes" ) |
043 | For Each gnt As Type In type.GetNestedTypes |
044 | Console.WriteLine( "{0}" , gnt.Name) |
054 | Private Sub ShowGetMembers(type As Type) |
055 | Console.WriteLine( "取得型別Members" ) |
056 | For Each mi As MemberInfo In type.GetMembers() |
057 | Console.WriteLine( " Member的 Type 及 名稱" ) |
058 | Console.WriteLine( " {0}:{1}" , mi.MemberType, mi.Name) |
069 | Private Sub ShowMemberType(mi As MemberInfo) |
072 | Select Case mi.MemberType |
073 | Case MemberTypes.Constructor |
074 | Case MemberTypes.Custom |
075 | Case MemberTypes. Event |
076 | Case MemberTypes.Field |
077 | Case MemberTypes.Method |
078 | Case MemberTypes.NestedType |
079 | Case MemberTypes. Property |
080 | Dim pi As PropertyInfo = CType (mi, PropertyInfo) |
081 | Console.WriteLine( " Property Type: {0}" , pi.PropertyType.Name) |
082 | Case MemberTypes.TypeInfo |
085 | Console.WriteLine( "什麼!完全沒有符合的成員!" ) |
093 | Sub ShowGetConstructors(type As Type) |
094 | Console.WriteLine( "取得型別Constructors" ) |
095 | For Each ci As ConstructorInfo In type.GetConstructors |
096 | Console.WriteLine( " IsSecuritySafeCritical: {0}" , ci.IsSecuritySafeCritical) |
106 | Sub ShowGetEvent(type As Type) |
107 | Console.WriteLine( "取得型別Events" ) |
108 | For Each ei As EventInfo In type.GetEvents |
109 | Console.WriteLine( " DeclaringType: {0}" , ei.DeclaringType) |
119 | Sub ShowGetFields(type As Type) |
120 | Console.WriteLine( "取得型別Fields" ) |
121 | For Each fi As FieldInfo In type.GetFields |
122 | Console.WriteLine( " FieldType: {0}" , fi.FieldType) |
132 | Sub ShowGetMethods(type As Type) |
133 | Console.WriteLine( "取得型別Methods" ) |
134 | For Each mi As MethodInfo In type.GetMethods |
135 | Console.WriteLine( "Method: {0}, IsPublic: {1}" , mi.GetBaseDefinition.Name, mi.IsPublic) |
- 顯示型別屬性,ShowGetProperties(type) --> PropertyInfo
- 顯示型別巢狀型別,ShowGetNestedTypes(type) --> Type
- 顯示型別成員,ShowGetMembers(type) --> MemberInfo
- 顯示型別建構子,ShowGetConstructors(type) --> ConstructorInfo
- 顯示型別事件,ShowGetEvent(type) --> EventInfo
- 顯示型別欄位,ShowGetFields(type) --> FieldInfo
- 顯示型別方法,ShowGetMethods(type) --> MethodInfo
不知道你有沒有發現,在以上 7 支副程式中,我們都是使用
Info 結尾的類別(除NestedTypes)來接收型別傳過來的資訊。再回去看看以上副程式,雖然很多,但其實
動作都是一樣的。你想要「屬性」資訊,那就用
PropertyInfo 來接收資訊,每個你想要的資訊內容都一個對應的 *Info 類別( 請參考
Reflection 類別 ),
記住這一點,那以上的副程式看起來比會簡單許多。
參考資料
- System.Type 屬性
- GetCustomAttributes
- Attribute.GetCustomAttributes
- Reflection 類別 (以這篇而言,是找 *Info 類別來看)
- Visual Basic - Reflection, 反映教學筆記(1) 前言
- Visual Basic - Reflection, 反映教學筆記(2) 基礎反映了解
- Visual Basic - Reflection, 反映教學筆記(3) 取得特定屬性
- Visual Basic - Reflection, 反映教學筆記(4) 取得型別的4種方法
沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。