使用MethodBase類的的GetMethodBody方法可以一個MethodBody對象,從這個對象可以得到一些對應方法的資訊。
MethodBody可以直接返回當前方法的IL原始位元組。還可以使用LocalVariables屬性返回一系列的VariableInfo對象,後者提供方法內本地變數的資訊。
其中MethodBody的InitLocals屬性和MaxStackSize分別指本地變數是否被初始化為0,和當前邏輯執行棧的最大長度。
當你僅在代碼中聲明變數時:
static void method()
{
int i;
}
即便是變數沒有被賦值,本地變數還是被初始化為0的,但是一般編譯器不允許使用未初始化的變數,當然實際上未初始化的變數已經被初始化為0了。上面的代碼會有如下IL:
.maxstack 0
.locals init ([0] int32 i)
init代表初始化本地變數,而MaxStack為0由於沒有任何實際操作,邏輯執行棧不需要任何空間。
下面是一個更有意義的代碼:
//+ using System.Reflection;
static void Main(string[] args)
{
var methodInfo = typeof(Program).GetMethod("doo");
//MethodBody對象
var methodBody = methodInfo.GetMethodBody();
Console.WriteLine("初始設定變數(init):{0}\n最大棧長度:{1}", methodBody.InitLocals, methodBody.MaxStackSize);
Console.WriteLine("本地變數資訊");
foreach (var varInfo in methodBody.LocalVariables)
Console.WriteLine("索引值:{0} 類型:{1} fix關鍵字:{2}", varInfo.LocalIndex, varInfo.LocalType, varInfo.IsPinned);
}
public static void doo()
{
object obj = 9;
for (int i = 0; i < 10; i++)
{
string s = i.ToString();
Console.WriteLine(obj.ToString() == s);
}
}
輸出:
初始設定變數(init):True
最大棧長度:2
本地變數資訊
索引值:0 類型:System.Object fix關鍵字:False
索引值:1 類型:System.Int32 fix關鍵字:False
索引值:2 類型:System.String fix關鍵字:False
索引值:3 類型:System.Boolean fix關鍵字:False
使用MethodBody的GetILAsByteArray方法可以返回方法的原始IL位元組。比如:
//+ using System.Reflection;
static void Main(string[] args)
{
var methodInfo = typeof(Program).GetMethod("PrintBytes");
PrintBytes(methodInfo.GetMethodBody().GetILAsByteArray());
}
public static void PrintBytes(byte[] bytes)
{
foreach(var b in bytes)
Console.Write("{0:X2} ",b);
Console.WriteLine();
}
輸出:
00 00 02 0B 16 0C 2B 19 07 08 91 0A 72 17 00 00 70 06 8C 18 00 00 01 28 15 00 00
0A 00 08 17 58 0C 08 07 8E 69 FE 04 0D 09 2D DD 28 16 00 00 0A 00 2A