Visual Basic - Reflection, 反映教學筆記(6) 暸解MethodBody

前面幾篇,我們可以透過型別、型別成員…等去瞭解型別的結果,但還是無法瞭解型別包含的程式碼,這時就可以透過 MethodBody 來瞭解。MethodBody 是一個特殊的物件,裝載著區域變數及實際中介語言( Intermediate Language;IL )。

在開始以下範例前,我們先進行一個準備工作。我們先從 MSDN 複製一個範例 Class 到我們的主程式碼的最下方。

#Region "MSDN中 MethodBase.GetMethodBody 方法範例"
''' <summary>
''' From MSDN: MethodBase.GetMethodBody 方法範例
''' http://msdn.microsoft.com/zh-tw/library/system.reflection.methodbody.aspx
''' </summary>
Public Class Example
    Public Shared Sub Main()
        ' 請從 MSDN 複製
    End Sub
End Class
#End Region

因為等一會的程式,必須從一個 Class 取得型別,從型別裡取得 MethodInfo ,再從 MethodInfo 取得 MethodBody,最後就能從 MethodBody 得到我們想要的資訊。


ShowMethodBody 副程式

程式中的 Example 就以上面我們從 MSDN 複製的 Class,然後一步步取得Type --> MethodInfo --> MethodBody。

#Region "顯示MethodBody相關資訊"
    ''' <summary>
    ''' MethodBody提供方法主體之中繼資料和 MSIL 的存取
    ''' </summary>
    Private Sub ShowMethodBody()
        ' GetType(Example):得到類別的型別
        ' GetMethod("MethodBodyExample"):指定得到型別裡的某個方法
        Dim mi As MethodInfo = GetType(Example).GetMethod("MethodBodyExample")
        Dim mb As MethodBody = mi.GetMethodBody()

        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
        Console.WriteLine()
        Console.ReadLine()
    End Sub
#End Region

最後,我們從 MethodBody 的 GetILAsByteArray() 連 IL 碼都能取得。我們來看執行結果。

ShowMethodBody 副程式執行結果

取得區域變數及堆疊大小
MaxStack: 3
Local Var (System.Int32) : 0
Local Var (System.String) : 1
Local Var (System.ArgumentException) : 2
Local Var (System.Exception) : 3
Local Var (System.Boolean) : 4

取得IL程式碼
001f2a0a72461b00700b000314fe01130411042c0b725a1b007073b900000a7a00036f5300000ad029000001281500000afe01130411042c0b729a1b007073ba00
000a7a00de747554000001252d0426162b1f250c283f00000a086fbb00000ad054000001281500000a6fbc00000a16fe03fe112672dc1b0070086fbb00000a2845
00000a00284000000ade2e25283f00000a0d0072101c0070096fbb00000a284500000a00284000000ade0e0020d90b00000a726e1c00700bdc00002a

好玩吧!以上是取得MSDN 範例中 Example 類別裡 MethodBodyExample 方法的結果,當然,你可以修改此副程式,傳入Class 名稱與 Method 名稱,就可彈性的解析出 MethodBody 的內容。我這裡為了範例簡化,都是使用副程式,我們在最後面的 OO 版本範例程式碼,就可以看到怎麼有彈性的玩這些範例程式碼。

參考資料

沒有留言:

張貼留言

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