在 Reflection (反映)中,支援不需要
提前參考就可以從組件中
動態地建立物件。我們可以動態去載入一個組件,不必事先 Import ( C# 中 using ),而且在組件中執行程式碼。
這一篇的內容比較複雜,要注意的地方我都寫成註解,所以我們直接來看相關副程式。我們先來看一個最簡單,也是一般在使用組件的方式。
UseHashtable 副程式
04 | Private Sub UseHashtable() |
05 | Console.WriteLine( "產生Hashtable" ) |
06 | Dim tb As New Hashtable() |
08 | Console.WriteLine( "Hash Count: {0}" , tb.Count) |
UseHashtable 副程式執行結果
一般方式,使用Hashtable
產生Hashtable
Hash Count: 1
以上是很一般使用 Hashtable 的方式,沒有任何特別之處。但如果我們是要透過動態程式碼的方式來撰寫,就會複雜很多。
使用動態程式碼撰寫 Hashtable 功能
動態程式碼的撰寫要比較了解物件導向,一個步驟一個頻驟建立出你想要的功能,從型別 --> 建構子 --> 方法 ...。
07 | Private Sub UseDynamicHashtable() |
08 | Console.WriteLine( "使用動態程式產生Hashtable" ) |
09 | Dim path As String = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll" |
10 | Dim asm As Assembly = Assembly .LoadFile(path) |
12 | Console.WriteLine( " 取得Hashtable型別" ) |
13 | Dim hashType As Type = asm. GetType ( "System.Collections.Hashtable" ) |
15 | Console.WriteLine( " 產生建構式" ) |
16 | Dim argType() As Type = Type.EmptyTypes |
21 | Dim ci As ConstructorInfo = hashType.GetConstructor(argType) |
23 | Dim newHash As Object = ci.Invoke( New Object () {}) |
33 | Console.WriteLine( " 取得Add方法" ) |
35 | Dim mi As MethodInfo = hashType.GetMethod( "Add" ) |
36 | Console.WriteLine( " 執行Add方法" ) |
42 | mi.Invoke(newHash, New Object () { "Hi" , "Hello" }) |
44 | Console.WriteLine( " 取得Count屬性" ) |
46 | Dim pi As PropertyInfo = hashType.GetProperty( "Count" ) |
51 | Dim count As Integer = CType (pi.GetValue(newHash, Nothing ), Integer ) |
53 | Console.WriteLine( "Hash Count: {0}" , count) |
56 | Console.WriteLine( "靜態成員輸出" ) |
58 | Dim consoleType As Type = GetType (Console) |
60 | Dim WriteLineMeth As MethodInfo = consoleType.GetMethod( "WriteLine" , New Type() { GetType ( String )}) |
63 | WriteLineMeth.Invoke( Nothing , New Object () { "Hash Count:" & count.ToString()}) |
上面程式碼內容比較多,但看久也會發現「順序」很重要。就是 Step by Step,一、要做什麼;二、要做什麼;…依步驟把內容寫出來。所以說,我們一個封裝很好的 Framework 可以用是非常幸福的事。
UseDynamicHashtable 執行結果
使用動態程式碼,產生 HttpUtility 型別,取得及執行HtmlEncode、HtmlDecode方法
這裡比較難懂,看過上面 UseDynamicHashtable() 之後,我們來看個簡單的。
04 | Sub UseDynamicHttpUtility() |
05 | Dim path As String = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Web.dll" |
06 | Dim asm As Assembly = Assembly .LoadFile(path) |
08 | Dim utilType As Type = asm. GetType ( "System.Web.HttpUtility" ) |
12 | Dim encode As MethodInfo = utilType.GetMethod( "HtmlEncode" , New Type() { GetType (System. String )}) |
13 | Dim decode As MethodInfo = utilType.GetMethod( "HtmlDecode" , New Type() { GetType (System. String )}) |
15 | Dim oStr As String = "This is Bruce & Sherry's Happy Family. <picture>.." |
16 | Console.WriteLine(oStr) |
20 | Dim encoded As String = CType (encode.Invoke( Nothing , New Object () {oStr}), String ) |
21 | Console.WriteLine(encoded) |
23 | Dim decoded As String = CType (decode.Invoke( Nothing , New Object () {encoded}), String ) |
24 | Console.WriteLine(decoded) |
有沒有簡單點。
UseDynamicHttpUtility 執行結果
動態程式碼, 使用HttpUtility
This is Bruce & Sherry's Happy Family.
This is Bruce & Sherry's Happy Family. <picture>.
This is Bruce & Sherry's Happy Family.
第一行是原始字串。第二行是 HtmlEncode 的結果。第三行是 HtmlDecode 的結果。
結論
簡單整理出動態程式碼有三個步驟:
- 取得型別
- 取得方法
- 使用方法
這一篇所需要的基礎知識比較多,算是比較難的一篇。加油!
參考資料
- Sytem.Type.GetMethod 方法 (String)
- System.Type.GetMethod 方法 (String, BindingFlags)
- System.Reflection.MethodBase.Invoke 方法 (Object, Object())
- System.Reflection.MethodBase.Invoke 方法 ((Object, BindingFlags, Binder, Object(), CultureInfo)
- 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(成員)
沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。