異常的處理也是程序中比較重要的一個部分,今天我們就針對用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);
本文配套源碼