異常的處理也是程序中比較重要的一個部分,今天我們就針對用IL書寫異常處 理代碼進行講解,首先照例給出要實現的類的C#代碼,如下:
ExceptionHandler
class ExceptionHandler { public static int ConvertToInt32(string str) { int num = 0; try { num = Convert.ToInt32(str); } catch (Exception ex) { Console.WriteLine(ex.Message); } return num; } }
代碼比較簡單,主要就是闡述如何在IL代碼中加入try、catch塊。這裡面會用 到ILGenerator類中的幾個新方法,介紹如下:
l BeginExceptionBlock:用來表示需要異常處理的代碼的開始,相當於C# 代碼中的try關鍵字;
l EndExceptionBlock:這個與BeginExceptionBlock配對,用來表示異常處 理的結束。注意:這裡的結束並不是只try語句塊的結束,而是指整個try catch 語句塊的結束;
l BeginCatchBlock:這個用來表示catch操作的開始,該方法需要傳入要需 要捕捉的一場的類型,程序中可以有多個BeginCatchBlock,即多個catch塊。
相關代碼如下:
Exception
TypeBuilder typeBuilder = moduleBuilder.DefineType ("ExceptionHandler", TypeAttributes.Public); MethodBuilder methodBuilder = typeBuilder.DefineMethod ("ConvertToInt32", MethodAttributes.Public | MethodAttributes.Static, typeof(Int32), new Type[] { typeof(string) }); ILGenerator methodIL = methodBuilder.GetILGenerator(); LocalBuilder num = methodIL.DeclareLocal(typeof(Int32)); //int num = 0; methodIL.Emit(OpCodes.Ldc_I4_0); methodIL.Emit(OpCodes.Stloc_0); //begin try Label tryLabel = methodIL.BeginExceptionBlock(); //num = Convert.ToInt32(str); methodIL.Emit(OpCodes.Ldarg_0); methodIL.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) })); methodIL.Emit(OpCodes.Stloc_0); //end try //begin catch 注意,這個時侯堆棧頂為異常信息ex methodIL.BeginCatchBlock(typeof(Exception)); //Console.WriteLine(ex.Message); methodIL.Emit(OpCodes.Call, typeof(Exception).GetMethod ("get_Message")); methodIL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //end catch methodIL.EndExceptionBlock(); //return num; methodIL.Emit(OpCodes.Ldloc_0); methodIL.Emit(OpCodes.Ret); Type type = typeBuilder.CreateType(); assemblyBuilder.Save(fileName);
本文配套源碼