异常处理在程序中也算是比较重要的一部分了,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) }));却能输出这部分的异常信息。可以看下反编译后的代码
三、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