Emit学习-进阶篇-异常处理

异常的处理也是程序中比较重要的一个部分,今天我们就针对用IL书写异常处理代码进行讲解,首先照例给出要实现的类的C#代码,如下:

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块。

  相关代码如下:

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);

你可能感兴趣的:(异常处理)