IL异常处理

异常处理在程序中也算是比较重要的一部分了,IL异常处理在C#里面实现会用到一些新的方法

1.BeginExceptionBlock:异常块代码开始,相当于try,但是感觉又不太像

2.EndExceptionBlock:异常块代码结束,BeginExceptionBlock相当于try,EndExceptionBlock却不是try结束。而是整个异常块处理的结束。

3.BeginCatchBlock:catch块代码

4.BeginFinallyBlock:finally块代码

5.ThrowException:抛出异常

下面我们就通过代码来实现一下。

一、异常信息捕捉

首先我们做一个简单的异常捕捉,然后输出对应的异常信息,首先给出C#代码:

            ;
            try
            {
                translationInt = Convert.ToInt32(translationStr);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return translationInt;

实现代码也比较简单

            string name = "IL4.Dynamic";
            string fileName = string.Format("{0}.dll", name);

            //构建程序集
            AssemblyName assemblyName = new AssemblyName(name);
            //应用程序集域
            AppDomain domain = AppDomain.CurrentDomain;
            //实例化一个AssemblyBuilder对象来实现动态程序集的构建
            AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);

            //定义模块(不加filename为瞬态模块,不持久)
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(name, fileName);

            //定义类型
            TypeBuilder typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public);

            MethodBuilder methodbuilder = typeBuilder.DefineMethod("ExceptionTest", MethodAttributes.Public, typeof(Int32), new Type[] { typeof(string) });
            ILGenerator IL = methodbuilder.GetILGenerator();
            LocalBuilder translationInt = IL.DeclareLocal(typeof(Int32));

            Type translationException = typeof(Exception);
            ConstructorInfo constructorInfo = translationException.GetConstructor(new Type[] { typeof(string) });
            MethodInfo exToString = translationException.GetMethod("ToString");

            IL.Emit(OpCodes.Ldc_I4_0);
            IL.Emit(OpCodes.Stloc_0);

            Label tryLabel = IL.BeginExceptionBlock();
            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) }));
            IL.Emit(OpCodes.Stloc_0);

            IL.BeginCatchBlock(typeof(Exception));
            IL.EmitCall(OpCodes.Callvirt, exToString, null);
            IL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
            IL.EndExceptionBlock();

            IL.Emit(OpCodes.Ldloc_0);
            IL.Emit(OpCodes.Ret);

二、抛出异常

程序中有时候,不仅要捕捉异常信息,有时候也是需要抛出对应的异常信息,throw new Exception("translation Exception");这时候就需要用到ThrowException,代码如下:

            IL.Emit(OpCodes.Ldstr, "translation Exception");
            IL.Emit(OpCodes.Newobj, constructorInfo);
            IL.ThrowException(typeof(newException));
            IL.Emit(OpCodes.Ldstr, ");
            IL.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) }));
            IL.Emit(OpCodes.Stloc_0);
            IL.EmitCall(OpCodes.Callvirt, exToString, null);
            IL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));

1.IL.Emit(OpCodes.Newobj, constructorInfo):相当于是一个 new Exception("translation Exception");

2.不过在这一步有一个疑点, IL.ThrowException(typeof(newException));是不会把异常信息"translation Exception"抛出,而在对应的操作IL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));却能输出这部分的异常信息。可以看下反编译后的代码

IL异常处理

三、finally处理

finally实现也是比较简单的,直接上代码把

            IL.BeginFinallyBlock();
            IL.Emit(OpCodes.Ldstr, ");
            IL.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) }));
            IL.Emit(OpCodes.Stloc_0);
            IL.EmitWriteLine("Finally");
            IL.EndExceptionBlock();

异常处理这块msdn写得也比较清楚,我也不多说了,示例代码ExceptionDemo

上一篇:札记:Java异常处理


下一篇:TM1680主从I2C设置.