Class 圖表
我們先看來整個 Class 圖表![]() |
| 圖一:Assembly Object-oriented Class (一) (點擊看大圖) |
![]() |
| 圖二:Assembly 相關類別 (點擊看大圖) |
![]() |
| 圖三:Attribute 相關類別(點擊看大圖) |
SuperAssembly.vb 抽象類別
我們先由 SuperAssembly 抽象類別開始,再一層一層看下去。Imports System.Reflection
''' <summary>
''' 抽象類別,統一進行建構子初始化及屬性條件設定
''' </summary>
''' <remarks></remarks>
Public MustInherit Class SuperAssembly
Public Property asm() As Assembly
Public Property assemblyPath() As String
' 預設值
Sub New()
assemblyPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll"
asm = Assembly.LoadFile(assemblyPath)
End Sub
' 組件路徑
Sub New(path As String)
assemblyPath = path
asm = Assembly.LoadFile(assemblyPath)
End Sub
' 執行的組件
Sub new(asm As Assembly )
Me.asm = asm
End Sub
End Class
ShowTypeAttributes 類別
Imports System.Reflection
Public Class ShowTypeAttributes
Inherits SuperAssembly
''' <summary>
''' 直接顯示型別相關資訊
''' </summary>
Sub Show()
Dim type As Type = GetType(String)
' Sample 5
GetTypeAttribute(type)
' Sample 6
ShowCustomAttribute(type)
' Sample 7
ShowTypeGetxxx(type)
End Sub
''' <summary>
''' 由物件取得型別後,額外顯示相關屬性
''' </summary>
''' <param name="type">Type (型別)</param>
Sub GetTypeAttribute(type As Type)
Console.WriteLine("型別的屬性")
Console.WriteLine("Assembly : {0}", type.Assembly)
Console.WriteLine("AQN : {0}", type.AssemblyQualifiedName)
Console.WriteLine("Attributes: {0}", type.Attributes)
Console.WriteLine("BaseType: {0}", type.BaseType)
Console.WriteLine("FullName: {0}", type.FullName)
Console.WriteLine("HasElementType: {0}", type.HasElementType)
Console.WriteLine("IsAbstract: {0}", type.IsAbstract)
Console.WriteLine("IsByRef: {0}", type.IsByRef)
Console.WriteLine("IsClass: {0}", type.IsClass)
Console.WriteLine("IsEnum: {0}", type.IsEnum)
Console.WriteLine("IsGenericType: {0}", type.IsGenericType)
Console.WriteLine("IsInterface: {0}", type.IsInterface)
Console.WriteLine("IsMarshalByRef: {0}", type.IsMarshalByRef)
Console.WriteLine("IsNotPublic: {0}", type.IsNotPublic)
Console.WriteLine("IsPrimitive: {0}", type.IsPrimitive)
Console.WriteLine("IsPublic: {0}", type.IsPublic)
Console.WriteLine("IsSealed: {0}", type.IsSealed)
Console.WriteLine("IsValueType: {0}", type.IsValueType)
Console.WriteLine("IsVisible: {0}", type.IsVisible)
Console.WriteLine("Module: {0}", type.Module)
Console.WriteLine("Name: {0}", type.Name)
Console.WriteLine("Namespace: {0}", type.Namespace)
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 由傳入參數,顯示相關型別相關屬性
''' </summary>
''' <param name="type">Type (型別)</param>
Sub ShowCustomAttribute(type As Type)
Console.WriteLine("取得類別屬性:")
For Each attr As Attribute In type.GetCustomAttributes(True)
Console.WriteLine(" {0}", attr.GetType.Name)
Next
Console.WriteLine()
End Sub
#Region "顯示型別相關 Getxxx 方法"
''' <summary>
''' 呼叫型別相關 Getxxx 測試方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowTypeGetxxx(type As Type)
ShowGetProperties(type)
ShowGetNestedTypes(type)
ShowGetMembers(type)
ShowGetConstructors(type)
ShowGetEvent(type)
ShowGetFields(type)
ShowGetMethods(type)
End Sub
''' <summary>
''' 簡單測試及顯示型別的屬性(Properties)
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Private Sub ShowGetProperties(type As Type)
Console.WriteLine("取得型別Properties")
For Each pi As PropertyInfo In type.GetProperties
Console.WriteLine("{0}", pi.Name)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別的NestedTypes
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Private Sub ShowGetNestedTypes(type As Type)
Console.WriteLine("取得型別NestedTypes")
For Each gnt As Type In type.GetNestedTypes
Console.WriteLine("{0}", gnt.Name)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetMembers() 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Private Sub ShowGetMembers(type As Type)
Console.WriteLine("取得型別Members")
For Each mi As MemberInfo In type.GetMembers()
Console.WriteLine(" Member的 Type 及 名稱")
Console.WriteLine(" {0}:{1}", mi.MemberType, mi.Name)
ShowMemberType(mi)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示MemberInfo裡MemberType成員,目前只讓 ShowGetMembers 呼叫
''' </summary>
''' <param name="mi">MemberInfo物件</param>
Private Sub ShowMemberType(mi As MemberInfo)
' MemberInfo 可藉由 MemberTypes 來判斷出型別的不同成員,注意,都是public。
' 簡單測試 MemberTypes.Property
Select Case mi.MemberType
Case MemberTypes.Constructor
Case MemberTypes.Custom
Case MemberTypes.Event
Case MemberTypes.Field
Case MemberTypes.Method
Case MemberTypes.NestedType
Case MemberTypes.Property
Dim pi As PropertyInfo = CType(mi, PropertyInfo)
Console.WriteLine(" Property Type: {0}", pi.PropertyType.Name)
Case MemberTypes.TypeInfo
Case MemberTypes.All
Case Else
Console.WriteLine("什麼!完全沒有符合的成員!")
End Select
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetConstructors 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowGetConstructors(type As Type)
Console.WriteLine("取得型別Constructors")
For Each ci As ConstructorInfo In type.GetConstructors
Console.WriteLine(" IsSecuritySafeCritical: {0}", ci.IsSecuritySafeCritical)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetEvents 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowGetEvent(type As Type)
Console.WriteLine("取得型別Events")
For Each ei As EventInfo In type.GetEvents
Console.WriteLine(" DeclaringType: {0}", ei.DeclaringType)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetFields 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowGetFields(type As Type)
Console.WriteLine("取得型別Fields")
For Each fi As FieldInfo In type.GetFields
Console.WriteLine(" FieldType: {0}", fi.FieldType)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetMethods 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowGetMethods(type As Type)
Console.WriteLine("取得型別Methods")
For Each mi As MethodInfo In type.GetMethods
Console.WriteLine("Method: {0}, IsPublic: {1}", mi.GetBaseDefinition.Name, mi.IsPublic)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
#End Region
End Class
ShowAssemblyInfo 類別
Imports System.Reflection
Public Class ShowAssemblyInfo
Inherits SuperAssembly
Sub AssemblyInfo()
Console.WriteLine("--- Assembly Information ---")
Console.WriteLine("FullName: {0}", asm.FullName)
Console.WriteLine("From GAC: {0}", asm.GlobalAssemblyCache)
Console.WriteLine("Path: {0}", asm.Location)
Console.WriteLine("Only Reflection: {0}", asm.ReflectionOnly)
Console.WriteLine("Version: {0}", asm.ImageRuntimeVersion)
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Sub ModuleInfo()
Dim mods() As [Module] = asm.GetModules
For Each md As [Module] In mods
ShowAssemblyModuleBasicInfo(md)
ShowAssemblyModuleTypesInfo(md)
ShowAssemblyModuleMethodInfo(md)
ShowAssemblyModuleFieldInfo(md)
ShowAssemblyModuleAttributeInfo(md)
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
Next
End Sub
Private Sub ShowAssemblyModuleBasicInfo(md As [Module])
Console.WriteLine("--- Module Basic Information ---")
Console.WriteLine("Name: {0}", md.Name)
Console.WriteLine("Assembly: {0}", md.Assembly)
Console.WriteLine("FQN: {0}", md.FullyQualifiedName)
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Private Sub ShowAssemblyModuleTypesInfo(md As [Module])
Console.WriteLine("--- Module Types Information ---")
Dim Types() As Type = md.GetTypes()
For Each type As Type In Types
Console.WriteLine("Type: {0}", type.Name)
Next
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Private Sub ShowAssemblyModuleMethodInfo(md As [Module])
Console.WriteLine("--- Module Method Information")
Dim methods() As MethodInfo = md.GetMethods()
For Each mi As MethodInfo In methods
Console.WriteLine("Method: {0}", mi.Name)
Next
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Private Sub ShowAssemblyModuleFieldInfo(md As [Module])
Console.WriteLine("---Module Field Information")
Dim fields() As FieldInfo = md.GetFields()
For Each fi As FieldInfo In fields
Console.WriteLine("Field: {0}", fi.Name)
Next
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Private Sub ShowAssemblyModuleAttributeInfo(md As [Module])
Console.WriteLine("--- Module Attribute Information ---")
Dim gcas() As Object = md.GetCustomAttributes(False)
For Each gca As Object In gcas
Console.WriteLine("GetCustomAttribute: {0}", gca.GetType.Name)
Next
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
End Class
GetAssemblyType4 類別
Imports System.Reflection
Public Class GetAssemblyType4
Inherits SuperAssembly
#Region "取得型別的4種方法"
Sub ShowTypeFromAssembly()
Dim asmTypes() As Type = asm.GetTypes()
Console.WriteLine("組件取得:")
For Each asmType In asmTypes
Console.WriteLine("Type: {0}", asmType.Name)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
Sub ShowTypeFromModule()
Dim mods() As [Module] = asm.GetModules()
Dim m As [Module] = mods(0)
Dim modTypes() As Type = m.GetTypes()
Console.WriteLine("模組取得:")
For Each modType In modTypes
Console.WriteLine("Type: {0}", modType.Name)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
Sub ShowTypeFromObject(objArray() As Object)
For Each obj In objArray
Dim objType As Type = obj.GetType()
Console.WriteLine("Object取得:")
Console.WriteLine("Type: {0}", objType.Name)
Console.WriteLine()
Dim gatgm As New GetAllTypeGetMethods
' 此Show為覆寫版本
gatgm.Show(objType)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
Sub ShowTypeFromVBGetType()
Dim vbtype As Type = GetType(Int32)
Console.WriteLine("VB GetType取得:")
Console.WriteLine("Type: {0}", vbtype.FullName)
Console.WriteLine()
Console.ReadLine()
End Sub
#End Region
End Class
ShowAssemblyInfo 類別
Imports System.Reflection
Public Class ShowAssemblyInfo
Inherits SuperAssembly
Sub AssemblyInfo()
Console.WriteLine("--- Assembly Information ---")
Console.WriteLine("FullName: {0}", asm.FullName)
Console.WriteLine("From GAC: {0}", asm.GlobalAssemblyCache)
Console.WriteLine("Path: {0}", asm.Location)
Console.WriteLine("Only Reflection: {0}", asm.ReflectionOnly)
Console.WriteLine("Version: {0}", asm.ImageRuntimeVersion)
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Sub ModuleInfo()
Dim mods() As [Module] = asm.GetModules
For Each md As [Module] In mods
ShowAssemblyModuleBasicInfo(md)
ShowAssemblyModuleTypesInfo(md)
ShowAssemblyModuleMethodInfo(md)
ShowAssemblyModuleFieldInfo(md)
ShowAssemblyModuleAttributeInfo(md)
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
Next
End Sub
Private Sub ShowAssemblyModuleBasicInfo(md As [Module])
Console.WriteLine("--- Module Basic Information ---")
Console.WriteLine("Name: {0}", md.Name)
Console.WriteLine("Assembly: {0}", md.Assembly)
Console.WriteLine("FQN: {0}", md.FullyQualifiedName)
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Private Sub ShowAssemblyModuleTypesInfo(md As [Module])
Console.WriteLine("--- Module Types Information ---")
Dim Types() As Type = md.GetTypes()
For Each type As Type In Types
Console.WriteLine("Type: {0}", type.Name)
Next
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Private Sub ShowAssemblyModuleMethodInfo(md As [Module])
Console.WriteLine("--- Module Method Information")
Dim methods() As MethodInfo = md.GetMethods()
For Each mi As MethodInfo In methods
Console.WriteLine("Method: {0}", mi.Name)
Next
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Private Sub ShowAssemblyModuleFieldInfo(md As [Module])
Console.WriteLine("---Module Field Information")
Dim fields() As FieldInfo = md.GetFields()
For Each fi As FieldInfo In fields
Console.WriteLine("Field: {0}", fi.Name)
Next
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
Private Sub ShowAssemblyModuleAttributeInfo(md As [Module])
Console.WriteLine("--- Module Attribute Information ---")
Dim gcas() As Object = md.GetCustomAttributes(False)
For Each gca As Object In gcas
Console.WriteLine("GetCustomAttribute: {0}", gca.GetType.Name)
Next
Console.WriteLine("--- 按 Ennter 繼續 ---")
Console.ReadLine()
End Sub
End Class
ShowMemberFilterFlags 類別
Imports System.Reflection
Public Class ShowMemberFilterFlags
Inherits SuperAssembly
Public Property flags As BindingFlags
''' <summary>
''' 由 BindingFlags 過濾所要取得的成員
''' 此測試由固定 String 型別來執行
''' </summary>
Sub ShowString()
' 由一般型別來測試
Console.WriteLine("由GetType(String)取得")
Dim type As Type = GetType(String)
' 設定想要的成員
' 重點:可以使用 Or, And … 等使用多個列舉
Console.WriteLine("BindingFlags條件為:Public、Instance、Static")
ShowMemberInfo(type.GetMembers(flags))
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 由 SuperAssembly 定義 asm, assemblyPath,也可自己改變
''' </summary>
Sub ShowAssembly()
Console.WriteLine(asm.FullName)
Console.WriteLine()
Console.ReadLine()
Dim types() As Type = asm.GetTypes()
For Each t As Type In types
Console.WriteLine("Type:{0}", t.Name)
Console.WriteLine(" BindingFlags條件為:DeclaredOnly、Public、Instance")
ShowMemberInfo(t.GetMembers(flags))
Console.WriteLine()
Console.ReadLine()
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 顯示 MemberInfo 物件相關資訊
''' </summary>
''' <param name="mi">MemberInfo 陣列物件</param>
''' <remarks></remarks>
Private Sub ShowMemberInfo(mi() As MemberInfo)
For Each m As MemberInfo In mi
Console.WriteLine(" Member: {0}, Type: {1}", m.Name, m.MemberType)
Next
End Sub
End Class
以上就是與 SuperAssembly 抽象類別及繼承類別的程式碼。
SuperAttribute 抽象類別
SuperAttribute 抽象類別,其中最重要的是 Type 屬性,能讓繼承類別能共用。初始化外,還定義一個 Show 方法,且繼承類別必須實作。''' <summary>
''' 抽象類別,統一進行建構子初始化
''' </summary>
Public MustInherit Class SuperAttribute
Public Property type() As Type
' 預設值
Sub New()
type = GetType(System.Int32)
End Sub
' 設定 Type 型別
Sub New(type As Type)
Me.type = type
End Sub
''' <summary>
''' 每個繼承的類別都必須覆寫Show()
''' </summary>
MustOverride Sub Show()
End Class
GetAllTypeGetMethods 類別
注意,Show 有兩個版本,一個無參數的 Show(),一個是有參數的 Show(type As Type),第二個多載的 Show(type As Type),讓你可以自行傳入型別(Type),然後顯示相關方法、屬性。Imports System.Reflection
Public Class GetAllTypeGetMethods
Inherits SuperAttribute
''' <summary>
''' 呼叫型別相關 Getxxx 測試方法
''' </summary>
Overrides Sub Show()
ShowTypeGetProperties(type)
ShowTypeGetNestedTypes(type)
ShowTypeGetMembers(type)
ShowTypeGetConstructors(type)
ShowTypeGetEvent(type)
ShowTypeGetFields(type)
ShowTypeGetMethods(type)
End Sub
' GetAssemblyType4.ShowTypeFromObject() 需要一個覆寫版本
Overloads Sub Show(type As Type)
ShowTypeGetProperties(type)
ShowTypeGetNestedTypes(type)
ShowTypeGetMembers(type)
ShowTypeGetConstructors(type)
ShowTypeGetEvent(type)
ShowTypeGetFields(type)
ShowTypeGetMethods(type)
End Sub
#Region "測試型別(Type)相關 GetXXX 函式"
''' <summary>
''' 簡單測試及顯示型別的屬性(Properties)
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowTypeGetProperties(type As Type)
Console.WriteLine("取得型別Properties")
For Each pi As PropertyInfo In type.GetProperties
Console.WriteLine("{0}", pi.Name)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別的NestedTypes
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowTypeGetNestedTypes(type As Type)
Console.WriteLine("取得型別NestedTypes")
For Each gnt As Type In type.GetNestedTypes
Console.WriteLine("{0}", gnt.Name)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetMembers() 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowTypeGetMembers(type As Type)
Console.WriteLine("取得型別Members")
For Each mi As MemberInfo In type.GetMembers()
Console.WriteLine(" Member的 Type 及 名稱")
Console.WriteLine(" {0}:{1}", mi.MemberType, mi.Name)
ShowMemberInfo(mi)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示MemberInfo裡MemberType成員,目前只讓 ShowGetMembers 呼叫
''' </summary>
''' <param name="mi">MemberInfo物件</param>
Sub ShowMemberInfo(mi As MemberInfo)
' MemberInfo 可藉由 MemberTypes 來判斷出型別的不同成員,注意,都是public。
' 簡單測試 MemberTypes.Property
Select Case mi.MemberType
Case MemberTypes.Constructor
Case MemberTypes.Custom
Case MemberTypes.Event
Case MemberTypes.Field
Case MemberTypes.Method
Case MemberTypes.NestedType
Case MemberTypes.Property
Dim pi As PropertyInfo = CType(mi, PropertyInfo)
Console.WriteLine(" Property Type: {0}", pi.PropertyType.Name)
Case MemberTypes.TypeInfo
Case MemberTypes.All
Case Else
Console.WriteLine("什麼!完全沒有符合的成員!")
End Select
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetConstructors 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowTypeGetConstructors(type As Type)
Console.WriteLine("取得型別Constructors")
For Each ci As ConstructorInfo In type.GetConstructors
Console.WriteLine(" IsSecuritySafeCritical: {0}", ci.IsSecuritySafeCritical)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetEvents 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowTypeGetEvent(type As Type)
Console.WriteLine("取得型別Events")
For Each ei As EventInfo In type.GetEvents
Console.WriteLine(" DeclaringType: {0}", ei.DeclaringType)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetFields 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowTypeGetFields(type As Type)
Console.WriteLine("取得型別Fields")
For Each fi As FieldInfo In type.GetFields
Console.WriteLine(" FieldType: {0}", fi.FieldType)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 簡單測試及顯示型別 GetMethods 方法
''' </summary>
''' <param name="type">型別 (即Type) 物件</param>
Sub ShowTypeGetMethods(type As Type)
Console.WriteLine("取得型別Methods")
For Each mi As MethodInfo In type.GetMethods
Console.WriteLine("Method: {0}, IsPublic: {1}", mi.GetBaseDefinition.Name, mi.IsPublic)
Next
Console.WriteLine()
Console.ReadLine()
End Sub
#End Region
End Class
GetCustomAttribute 類別
Public Class GetCustomAttribute
Inherits SuperAttribute
Overrides Sub Show()
Console.WriteLine("取得類別屬性:")
For Each attr As Attribute In type.GetCustomAttributes(True)
Console.WriteLine(" {0}", attr.GetType.Name)
Next
Console.WriteLine()
End Sub
End Class
SuperAttribute 抽象類別
Public Class GetTypeAttribute
Inherits SuperAttribute
Overrides Sub Show()
Console.WriteLine("型別的屬性")
Console.WriteLine("Assembly : {0}", type.Assembly)
Console.WriteLine("AQN : {0}", type.AssemblyQualifiedName)
Console.WriteLine("Attributes: {0}", type.Attributes)
Console.WriteLine("BaseType: {0}", type.BaseType)
Console.WriteLine("FullName: {0}", type.FullName)
Console.WriteLine("HasElementType: {0}", type.HasElementType)
Console.WriteLine("IsAbstract: {0}", type.IsAbstract)
Console.WriteLine("IsByRef: {0}", type.IsByRef)
Console.WriteLine("IsClass: {0}", type.IsClass)
Console.WriteLine("IsEnum: {0}", type.IsEnum)
Console.WriteLine("IsGenericType: {0}", type.IsGenericType)
Console.WriteLine("IsInterface: {0}", type.IsInterface)
Console.WriteLine("IsMarshalByRef: {0}", type.IsMarshalByRef)
Console.WriteLine("IsNotPublic: {0}", type.IsNotPublic)
Console.WriteLine("IsPrimitive: {0}", type.IsPrimitive)
Console.WriteLine("IsPublic: {0}", type.IsPublic)
Console.WriteLine("IsSealed: {0}", type.IsSealed)
Console.WriteLine("IsValueType: {0}", type.IsValueType)
Console.WriteLine("IsVisible: {0}", type.IsVisible)
Console.WriteLine("Module: {0}", type.Module)
Console.WriteLine("Name: {0}", type.Name)
Console.WriteLine("Namespace: {0}", type.Namespace)
Console.WriteLine()
Console.ReadLine()
End Sub
End Class
以上就是 SuperAttribute 抽象類別及繼承的類別,唯一要注意是多載那個地方的使用。
ShowMethodBody
在這裡,你能發現使用Object-oriented(物件導向)比使用副程式彈性多了。Imports System.Reflection
Public Class ShowMethodBody
''' <summary>
''' MethodBody提供方法主體之中繼資料和 MSIL 的存取
''' </summary>
Public Sub ShowExample()
' GetType(Example):得到類別的型別
' GetMethod("MethodBodyExample"):指定得到型別裡的某個方法
Dim mi As MethodInfo = GetType(Example).GetMethod("MethodBodyExample")
Dim mb As MethodBody = mi.GetMethodBody()
ShowMethodBodyInfo(mb)
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 取得 ShowMethodBody (即自己Self)的 ShowExample 的 MethodBody
''' </summary>
Public Sub ShowSelf()
Dim mi As MethodInfo = GetType(ShowMethodBody).GetMethod("ShowExample")
Dim mb As MethodBody = mi.GetMethodBody()
ShowMethodBodyInfo(mb)
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 顯示 MethodBody 堆疊大小,區域變數, IL Code
''' </summary>
''' <param name="mb">方法主體</param>
Protected Sub ShowMethodBodyInfo(mb As MethodBody)
Console.WriteLine("取得堆疊大小及區域變數")
Console.WriteLine("MaxStack: {0}", mb.MaxStackSize)
For Each local As LocalVariableInfo In mb.LocalVariables
Console.WriteLine("Local Var ({0}) : {1}", local.LocalType, local.LocalIndex)
Next
Console.WriteLine()
Console.WriteLine("取得IL程式碼")
For Each b As Byte In mb.GetILAsByteArray()
Console.Write("{0:x2}", b)
Next
End Sub
End Class
在之前濕透了的範例中,因為都是副程式,所以我們複製了一個 MSDN 範例 Class,才有辦法讓程式順利運作,但在這裡,如我們的 ShowSelf() 一樣,類別多的是,想怎麼用都行。
DynamicCode 類別
注意最前面二行的註解即可,我們讓函式自己決定要載入的組件,其他一樣。Imports System.Reflection
Public Class DynamicCode
' 因為我們 assemblyPath 及 asm 必須固定,以防錯誤,不去繼承 SuperAssembly 來使用。
' 且不許使用者來修改,所以為 Private
Private Property asm() As Assembly
Private Property assemblyPath() As String
Sub new()
End Sub
''' <summary>
''' 使用一般 Hashtable 方法來顯示
''' </summary>
Sub GeneralHashtable()
Console.WriteLine("產生Hashtable")
Dim tb As New Hashtable()
tb.Add("Hi", "Hello")
Console.WriteLine("Hash Count: {0}", tb.Count)
Console.WriteLine()
Console.ReadLine()
End Sub
''' <summary>
''' 一般而言,建立動態程式碼是在開發及編譯應用程式階段時,需要載入尚未參考的程式碼。
''' 而非像下例使用的 UseDynamicHashtable 裡的 mscorlib.dll (一般應用程式都會預設載入此組件)
''' 使用動態程式碼,產生 Hashtable,取得及執行add方法、取得Count屬性。
''' 此範例複雜些,請注意註解及參考MSDN各物件說明
''' </summary>
Sub DynamicHashtable()
Console.WriteLine("使用動態程式產生Hashtable")
assemblyPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"
asm = Assembly.LoadFile(assemblyPath)
' 取得 Hashtable 型別, 注意下面ci取得建構式
Console.WriteLine(" 取得Hashtable型別")
Dim hashType As Type = asm.GetType("System.Collections.Hashtable")
Console.WriteLine(" 產生建構式")
Dim argType() As Type = Type.EmptyTypes
' 用 ConstructorInfo 來建構這個新型別
' Type.GetConstructor(...),有三個多載,我們使用第一個來測試
' GetConstructor(Type()),搜尋其參數符合在指定陣列中(Type())的型別的公用執行個體建構函式。
' 我們傳入一個「空的型別陣列」 argType()
Dim ci As ConstructorInfo = hashType.GetConstructor(argType)
' 呼叫Invoke,產生一個空物件,即一個空的 Hashtable
Dim newHash As Object = ci.Invoke(New Object() {})
'' --- 這是另一種寫法 ---
'' --- 我們傳入一個含Int32型別的陣列 ---
'Dim argTypes() As Type = New Type() {GetType(System.Int32)}
'Dim ci As ConstructorInfo = hashType.GetConstructor(argTypes)
'' --- 注意,因為我們傳入的型別陣列為 Int32,所以產生物件時必須給一個 Int32 值---
'' --- 值可以隨便給,只要是在符合 Int32 範圍即可 ---
'Dim newHash As Object = ci.Invoke(New Object() {1024})
Console.WriteLine(" 取得Add方法")
' 取得型別方法
Dim mi As MethodInfo = hashType.GetMethod("Add")
Console.WriteLine(" 執行Add方法")
' 執行取得的方法
' Public Function Invoke ( obj As Object, parameters As Object() ) As Object
' obj:物件,要在其上叫用方法或建構函式。
' parameters:叫用方法或建構函式的引數清單。
' 我要執行 newHash 物件(Hashtable) 的 add 方法,參數是 "Hi", "Hello"
mi.Invoke(newHash, New Object() {"Hi", "Hello"})
Console.WriteLine(" 取得Count屬性")
' 取得Count屬性
Dim pi As PropertyInfo = hashType.GetProperty("Count")
' Public Overridable Function GetValue ( obj As Object, index As Object() ) As Object
' obj:其屬性值將被傳回的物件。
' index:索引屬性的選擇性索引值。非索引屬性的這個值應為 Nothing。
' 取出 Count 值
Dim count As Integer = CType(pi.GetValue(newHash, Nothing), Integer)
Console.WriteLine("Hash Count: {0}", count)
Console.WriteLine()
Console.WriteLine("靜態成員輸出")
' 使用靜態成員
Dim consoleType As Type = GetType(Console)
' 注意,我們傳入的型別陣列的型別是String
Dim WriteLineMeth As MethodInfo = consoleType.GetMethod("WriteLine", New Type() {GetType(String)})
' 靜態成員可以不需要建立一個物件,傳入 Nothing
' 型別陣列的型別是String,count.ToString()
WriteLineMeth.Invoke(Nothing, New Object() {"Hash Count:" & count.ToString()})
' 如果我們傳入的型別陣列的型別是Int32
'Dim WriteLineMeth As MethodInfo = consoleType.GetMethod("WriteLine", New Type() {GetType(Int32)})
' 型別陣列的型別是Int32,count (Integer) 直接輸出即可
'WriteLineMeth.Invoke(Nothing, New Object() {count})
End Sub
''' <summary>
''' 使用動態程式碼,產生 HttpUtility 型別,取得及執行HtmlEncode、HtmlDecode方法。
''' </summary>
Sub DynamicHttpUtility()
assemblyPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Web.dll"
asm = Assembly.LoadFile(assemblyPath)
' 取得型別
Dim utilType As Type = asm.GetType("System.Web.HttpUtility")
' 重點一
' 取得方法
Dim encode As MethodInfo = utilType.GetMethod("HtmlEncode", New Type() {GetType(System.String)})
Dim decode As MethodInfo = utilType.GetMethod("HtmlDecode", New Type() {GetType(System.String)})
Dim oStr As String = "This is Bruce & Sherry's Happy Family. <picture>."
Console.WriteLine(oStr)
' 重點二
' 使用方法
Dim encoded As String = CType(encode.Invoke(Nothing, New Object() {oStr}), String)
Console.WriteLine(encoded)
Dim decoded As String = CType(decode.Invoke(Nothing, New Object() {encoded}), String)
Console.WriteLine(decoded)
Console.Read()
End Sub
End Class
RunTimeCreateAssembly 類別
我們新增兩個屬性,讓使用者可以自己決定組件名稱和組件版本。唯一注意,組件版本必須使用 New Version("x.x.x.x") 來給值。絕大部份是使用 Emit 類別。Imports System.Reflection
Imports System.Reflection.Emit
Public Class RunTimeCreateAssembly
' 組件名稱
Public Property AssemblyName() As String
' 組件版本,必須使用 New Version("x.x.x.x") 來給值
Public Property AssemblyVersion() As Version
''' <summary>
''' 建立動態組件
''' </summary>
Sub Create()
' 1. 建立組件
Console.WriteLine("定義組件")
Dim tempName As New AssemblyName()
tempName.Name = AssemblyName
tempName.Version = AssemblyVersion
' 使用 DefineDynamicAssembly 動態產生組件
Dim AssemBL As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(tempName, AssemblyBuilderAccess.RunAndSave)
' 2. 建立模組
Console.WriteLine("定義模組")
' DefineDynamicModule 動態產生模組
' 如果要建立一個單一檔案的組件,並將此組件序列化在磁碟之中,最後的Save名稱必須與以下DefineDynamicModule裡名稱相同。
Dim ModuleBL As ModuleBuilder = AssemBL.DefineDynamicModule(tempName.Name, tempName.Name & ".dll")
' 3. 建立型別
Console.WriteLine("定義型別")
' DefineType 動態產生型別
Dim BruceType As TypeBuilder = ModuleBL.DefineType("KKBruceType", TypeAttributes.Class Or TypeAttributes.Public)
' 指定父類別及介面給DefineType
'Dim tb As TypeBuilder = mb.DefineType("KKBruceMyNewType", TypeAttributes.Class Or TypeAttributes.Public,
' GetType(Hashtable),
' New Type() {GetType(IDisposable)})
' 4. 建立成員
Console.WriteLine("定義相關成員")
' 4.1 建立建構子
Console.WriteLine(" 定義建構子")
' MethodAttributes代表建構子的類型
'Dim ConstructorBL As ConstructorBuilder = BruceType.DefineDefaultConstructor(MethodAttributes.Public)
' 4.2 利用ConstructorBuilder建立ILGenerator物件
' --- 註:執行會產生錯誤 ---
' --- 註:依MSDN查詢:Runtime 會為預設建構函式產生程式碼。因此,如果嘗試取得 ILGenerator,則會擲回例外狀況。 ---
'Console.WriteLine(" 建立ILGenerator物件")
' ILGenerator 可產生 Microsoft Intermediate Language (MSIL) 指令。
'Dim codeGen As ILGenerator = ConstructorBL.GetILGenerator()
' Emit:多載。放置指令到 Just-In-Time (JIT) 編譯器的 Microsoft Intermediate Language (MSIL) 資料流中。
' OpCodes 類別:提供 Microsoft Intermediate Language (MSIL) 指令的欄位表示,以用於 ILGenerator 類別成員 (例如 Emit) 的發出。
' Ret欄位:從目前方法傳回,將被呼叫端評估堆疊的傳回值 (如果有的話) 推入至呼叫端的評估堆疊。
'codeGen.Emit(OpCodes.Ret)
' 4.3 建立方法
Console.WriteLine(" 定義方法")
Dim MethodBLOne As MethodBuilder = BruceType.DefineMethod("AddStringOne", MethodAttributes.Public, Nothing, New Type() {GetType(String)})
' 第三個參數:建新新方法的回傳型別
' 第四個參數:參數型別
Dim MethodBLTwo As MethodBuilder = BruceType.DefineMethod("AddStringTwo", MethodAttributes.Public Or MethodAttributes.Static,
Nothing,
New Type() {GetType(String)})
' 4.4 建立私有欄位
Console.WriteLine(" 定義私有欄位")
Dim FieldBL As FieldBuilder = BruceType.DefineField("_count", GetType(Int32), FieldAttributes.Private)
' 4.5 建立屬性
Console.WriteLine(" 定義屬性")
' PropertyAttributes.None 列舉常數不能定義所有的屬性
Dim PropertyBL As PropertyBuilder = BruceType.DefineProperty("Count", PropertyAttributes.None, GetType(Int32), Type.EmptyTypes)
' 4.6 在方法中定義設得或設定屬性值
Console.WriteLine(" 定義方法中設得或設定屬性值")
' 注意,使用MethodAttributes
Dim getMethodAttributes As MethodAttributes = MethodAttributes.Public Or
MethodAttributes.SpecialName Or
MethodAttributes.HideBySig
Dim propGet As MethodBuilder = BruceType.DefineMethod("get_Count", getMethodAttributes, GetType(Int32), Type.EmptyTypes)
' 讓方法可以設定與取得屬性值
PropertyBL.SetGetMethod(propGet)
' 5. 建立型別
Console.WriteLine("產生新型別")
Console.WriteLine(" 產生所有方法的ILGenerator")
' --- 超重要 ---
' --- 請參考方法 summary ---
RunMethodBLGetILGenerator(MethodBLOne)
RunMethodBLGetILGenerator(MethodBLTwo)
RunMethodBLGetILGenerator(propGet)
Console.Write(" 產生型別")
Dim KKBruceType As Type = BruceType.CreateType()
' 5.1 顯示此型別方法
Console.WriteLine()
Console.WriteLine(" 顯示型別方法(注意我們產生動態產生的方法)")
GetRunTimeAssemblyMethods(KKBruceType)
Console.WriteLine()
Console.ReadLine()
' 6. 儲存組件到磁碟中
Console.WriteLine("儲存組件到磁碟中...")
' 一但被寫入到磁碟中,任何程式都可以載入這個組件使用。
AssemBL.Save(tempName.Name & ".dll")
Console.WriteLine("儲存完成。(請""開啟專案目錄""下「\bin\Debug」查看產生的動態組件 " & tempName.Name & ".dll")
Console.ReadLine()
End Sub
''' <summary>
''' 傳回這個方法的 ILGenerator
''' </summary>
''' <param name="methodInstance">MethodBuilder 的執行個體</param>
''' <remarks>
''' 建立型別之前要為所有 MethodBuilder 執行 GetILGenerator()。
''' 不然會產生一個「方法 'xxx' 沒有方法主體。」的錯誤,這裡 Debug 花了我好久!XD!
''' 參考:http://msdn.microsoft.com/zh-tw/library/system.reflection.emit.methodbuilder.definegenericparameters%28VS.85%29.aspx 範例才找出解法
''' </remarks>
Private Sub RunMethodBLGetILGenerator(methodInstance As MethodBuilder)
' MethodBuilder.GetILGenerator()
' 傳回這個方法的 ILGenerator,使用預設 Microsoft Intermediate Language (MSIL) 資料流的 64 位元大小。
Dim ilgen As ILGenerator = methodInstance.GetILGenerator()
ilgen.Emit(OpCodes.Ldnull)
ilgen.Emit(OpCodes.Ret)
End Sub
''' <summary>
''' 取得動態組件方法屬性
''' </summary>
''' <param name="KKBruceType">型別</param>
Private Sub GetRunTimeAssemblyMethods(ByVal KKBruceType As Type)
Console.WriteLine(" Full Name: {0}", KKBruceType.FullName)
For Each m As MemberInfo In KKBruceType.GetMethods()
Console.WriteLine(" Member({0}):{1}", m.MemberType, m.Name)
Next
End Sub
End Class
這邊你也能學我,寫個抽象類別,去統一建構子及屬性,在建構子裡給屬性初始值,預設程式的錯誤。前面我已經寫了二個例子,這一個我就不改寫了,留給各位當練習題。
SampleFactory 類別
工廠終於來了,沒有工廠就沒有實體!!!''' <summary>
''' 簡單工廠模式
''' </summary>
Public Class SampleFactory
Public Shared Function Create(sampleName As String) As Object
Dim SampleObject As Object = Nothing
Select Case sampleName
Case "Sample1"
SampleObject = New ShowAssemblyInfo()
Case "Sample2"
SampleObject = New ShowAttributeInfo()
Case "Sample3"
SampleObject = New GetAssemblyType4()
Case "Sample4"
SampleObject = New ShowTypeAttributes()
Case "Sample5"
SampleObject = New ShowMethodBody()
Case "Sample6"
SampleObject = New ShowMemberFilterFlags()
Case "Sample7"
SampleObject = New DynamicCode()
Case "Sample8"
SampleObject = New RunTimeCreateAssembly()
End Select
Return SampleObject
End Function
End Class
依傳入的關鍵字來建立及回傳相對應的實體。
Module1.vb 主程式
一樣的選擇題小遊戲,注意,實體化是透過工廠「SampleFactory.Create()」,而且透過屬性取給值非常方便。Module Module1
Sub Main()
Dim flags As Boolean = True
Dim selectNumber As Integer = 0
While flags
If flags = True Then
If selectNumber >= 0 AndAlso selectNumber <= 8 Then
Console.WriteLine("請輸入想執行的範例(0為結束),輸入完請按 Enter。")
Console.Write("請輸入 1 ~ 8 (預設1):")
Try
selectNumber = Console.ReadLine()
Catch ex As Exception
' 如果使用者未輸入按 Enter,會引發錯誤!
Console.WriteLine("未輸入,本程式將結束 ...")
selectNumber = 0
End Try
Else
Console.WriteLine("本程式將結束 ...")
selectNumber = 0
End If
End If
Select Case selectNumber
Case 0
flags = False
Console.WriteLine("請按 Enter 結束本程式.")
Case 1
Console.WriteLine()
Console.WriteLine("Sample 1")
Console.WriteLine("")
' ----------------------------------
' ShowAssemblyInfo.vb 測試
' ----------------------------------
Dim Sample1 As ShowAssemblyInfo = SampleFactory.Create("Sample1")
Sample1.AssemblyInfo()
Sample1.ModuleInfo()
Console.WriteLine("---改變組件路徑---")
Console.ReadLine()
' 這裡可以改成讓使用者自己輸入
Sample1.assemblyPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Drawing.dll"
Sample1.asm = System.Reflection.Assembly.LoadFile(Sample1.assemblyPath)
Sample1.AssemblyInfo()
Sample1.ModuleInfo()
Console.WriteLine()
Console.WriteLine("---載入正在執行的組件---")
Console.ReadLine()
Sample1.asm = System.Reflection.Assembly.GetExecutingAssembly
Sample1.AssemblyInfo()
Sample1.ModuleInfo()
Console.WriteLine()
Console.WriteLine("Sample 1 結束.")
Console.WriteLine()
Case 2
Console.WriteLine()
Console.WriteLine(" Sample 2")
Console.WriteLine()
' ----------------------------------
' ShowAttributeInfo.vb 測試
' 請參考 My Project\AssemblyInfo.vb 裡的屬性。
' ----------------------------------
Dim Sample2 As ShowAttributeInfo = SampleFactory.Create("Sample2")
Sample2.ShowAttributeInfo()
Sample2.assemblyPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Drawing.dll"
Sample2.ShowAttributeInfo()
Sample2.asm = System.Reflection.Assembly.GetExecutingAssembly
Sample2.ShowAttributeInfo()
Console.WriteLine()
Console.WriteLine("Sample 2 結束.")
Console.WriteLine()
Case 3
Console.WriteLine()
Console.WriteLine("Sample 3")
Console.WriteLine("請參考 My Project\AssemblyInfo.vb 裡的屬性。")
Console.WriteLine()
' ----------------------------------
' ShowAttributeInfo.vb 測試
' 請參考 My Project\AssemblyInfo.vb 裡的屬性。
' ----------------------------------
Dim Sample3 As GetAssemblyType4 = SampleFactory.Create("Sample3")
Sample3.ShowTypeFromAssembly()
Sample3.ShowTypeFromModule()
Sample3.assemblyPath = "c:\windows\microsoft.net\framework\v4.0.30319\system.drawing.dll"
Sample3.ShowTypeFromAssembly()
Sample3.ShowTypeFromModule()
Sample3.asm = System.Reflection.Assembly.GetExecutingAssembly()
Sample3.ShowTypeFromAssembly()
Sample3.ShowTypeFromModule()
' string, int32, double, boolean
Dim t() As Object = {"string", 1, 0.5, True}
Sample3.ShowTypeFromObject(t)
Sample3.ShowTypeFromVBGetType()
Console.WriteLine()
Console.WriteLine("Sample 3 結束.")
Console.WriteLine()
Case 4
Console.WriteLine()
Console.WriteLine("Sample 4")
Console.WriteLine()
' ----------------------------------
' 1. 使用型別
' 2. 取得型別類別屬性
' 3. 取得型別物件
' ----------------------------------
Dim Sample4 As ShowTypeAttributes = SampleFactory.Create("Sample4")
Sample4.Show()
Console.WriteLine()
Console.WriteLine("Sample 4 結束.")
Console.WriteLine()
Case 5
Console.WriteLine()
Console.WriteLine("Sample 5")
Console.WriteLine()
' ----------------------------------
' Example 類別,請參考:http://msdn.microsoft.com/zh-tw/library/system.reflection.methodbody.aspx
' ----------------------------------
Dim Sample5 As ShowMethodBody = SampleFactory.Create("Sample5")
' 使用 MSDN Example Class
Sample5.ShowExample()
' 使用 ShowMethodBody Class
Sample5.ShowSelf()
Console.WriteLine()
Console.WriteLine("Sample 5 結束.")
Console.WriteLine()
Case 6
Console.WriteLine()
Console.WriteLine("Sample 6")
Console.WriteLine()
' ----------------------------------
' BindingFlags 取得特定成員
' ----------------------------------
Dim Sample6 As ShowMemberFilterFlags = SampleFactory.Create("Sample6")
' 設定 ShowString 使用 flags
Sample6.flags = System.Reflection.BindingFlags.Public Or
System.Reflection.BindingFlags.Instance Or
System.Reflection.BindingFlags.Static
Sample6.ShowString()
' 預設建構子裡的 Assembly
' 設定 ShowAssembly 使用 flags
Sample6.flags = System.Reflection.BindingFlags.DeclaredOnly Or
System.Reflection.BindingFlags.Public Or
System.Reflection.BindingFlags.Instance
Sample6.ShowAssembly()
' 現在正在執行的 Assembly
Sample6.asm = System.Reflection.Assembly.GetExecutingAssembly()
Sample6.ShowAssembly()
' 指定 ShowAssembly 條件
Sample6.assemblyPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.ServiceProcess.dll"
Sample6.asm = System.Reflection.Assembly.LoadFile(Sample6.assemblyPath)
Sample6.ShowAssembly()
Console.WriteLine()
Console.WriteLine("Sample 6 結束.")
Console.WriteLine()
Case 7
Console.WriteLine()
Console.WriteLine("Sample 7")
Console.WriteLine()
' ----------------------------------
' 動態程式碼
' ----------------------------------
Dim Sample7 As DynamicCode = SampleFactory.Create("Sample7")
Sample7.GeneralHashtable()
Sample7.DynamicHashtable()
Sample7.DynamicHttpUtility()
Console.WriteLine()
Console.WriteLine("Sample 7 結束.")
Console.WriteLine()
Case 8
Console.WriteLine()
Console.WriteLine("Sample 8")
' ----------------------------------
' 執行環境中產生程式碼
' ----------------------------------
Dim Sample8 As RunTimeCreateAssembly = SampleFactory.Create("Sample8")
' 先指定要產生組件名稱及版本
Sample8.AssemblyName = "KKBruceSample8Assembly"
Sample8.AssemblyVersion = New Version("1.1.1.1")
Sample8.Create()
Console.WriteLine()
Console.WriteLine("Sample 8 結束.")
Console.WriteLine()
Case Else
Console.WriteLine("輸入數字錯誤!")
End Select
End While
Console.ReadLine()
End Sub
End Module
最後一個 Sample8,各位試著動手改寫為抽象類別,然後在不給組件名稱和版本的情況下,去執行,讓你的建構子去給預設值。
結論
在 MSDN 之中,有很大一部分在討論「泛型」的 Reflection,不過我自認為理解層度不足,等有一天讓我看懂了,或有"通"的感覺,我再來分享。經過前九篇的教學筆記,應該想要看懂大部分 Reflecion 程式碼應該不是問題。另外,撰寫這第十篇 Reflection,我真的認為「重構」這本書實在很不簡單,把平常又重要的事情整理出一套系統化方法,讓我們可以有效學習,程式人員必需人手一本的書,不管你寫不寫物件導向,只要是有在寫程式,你就必須一讀。
濕、乾二重奏 - 下載原始專案檔
檔案內容包含濕透了 AssemblyDemo 專案(即第九篇的檔案),烘乾的 AssemblyDemoOO 專案。解壓縮密碼:KKBruce
參考資料
- Visual Basic - Reflection, 反映教學筆記(1) 前言
- Visual Basic - Reflection, 反映教學筆記(2) 基礎反映了解
- Visual Basic - Reflection, 反映教學筆記(3) 取得特定屬性
- Visual Basic - Reflection, 反映教學筆記(4) 取得型別的4種方法
- Visual Basic - Reflection, 反映教學筆記(5) 取得型別相關屬性
- Visual Basic - Reflection, 反映教學筆記(6) 暸解MethodBody
- Visual Basic - Reflection, 反映教學筆記(7) - BindingFlags 過濾 Member(成員)
- Visual Basic - Reflection, 反映教學筆記(8) 執行動態程式碼
- Visual Basic - Reflection, 反映教學筆記(9) 執行環境中產生程式碼
- Visual Basic OOP



沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。