.NET(C#):Emit创建异常处理的方法
目录 Emit异常处理流程 复制代码 代码如下: static void doo(Exception e) { try { throw e; } catch (ApplicationException ex) { Console.WriteLine("捕获ApplicationException"); } catch { Console.WriteLine("捕获Exception"); } finally { Console.WriteLine("finally块"); } } 我们将用反射Emit创建一个这样的方法。 其实IL中的异常处理代码还是比较复杂的,你可以在Reflector下看看异常处理的IL代码。不过好在ILGenerator类提供了一些方便的方法来创建异常处理代码。 基本套路就是用如下ILGenerator的方法: BeginExceptionBlock方法来开始异常处理代码(相当于try)。 来看代码: 复制代码 代码如下: //+ using System.Reflection; //+ using System.Reflection.Emit; static void Main(string[] args) dm.Invoke(null,new object[] { new ApplicationException() }); dm.Invoke(null,new object[] { new Exception() }); } { var dm = new DynamicMethod("",null,new Type[] { typeof(Exception) }); var ilgen = dm.GetILGenerator(); //try { ilgen.BeginExceptionBlock(); //加载第一个参数,并throw ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Throw); ilgen.BeginCatchBlock(typeof(ApplicationException)); //清空栈上的异常对象 ilgen.Emit(OpCodes.Pop); ilgen.EmitWriteLine("捕获ApplicationException"); ilgen.BeginCatchBlock(typeof(Exception)); //清空栈上的异常对象 ilgen.Emit(OpCodes.Pop); ilgen.EmitWriteLine("捕获Exception"); ilgen.BeginFinallyBlock(); ilgen.EmitWriteLine("finally块"); //结束整个处理块 ilgen.EndExceptionBlock(); ilgen.Emit(OpCodes.Ret); return dm; } 输出: 复制代码 代码如下: 捕获ApplicationException finally块 捕获Exception finally块 返回目录 显示Exception对象的Message属性 上面的代码并没有显示Exception对象的Message属性,上面主要是介绍Emit异常处理的流程,下面来看看怎样显示Message属性,如果是直接输出当然简单了,不过如果用到Console.WriteLine的格式字符串的话,需要在catch代码块中用一个临时变量。 如下代码: 复制代码 代码如下: //+ using System.Reflection; //+ using System.Reflection.Emit; dm.Invoke(null,new object[] { new Exception("来自Mgen!") }); static DynamicMethod GetMethod() var dm = new DynamicMethod("",new Type[] { typeof(Exception) }); var ilgen = dm.GetILGenerator(); //try { ilgen.BeginExceptionBlock(); //加载第一个参数,并throw ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Throw); ilgen.BeginCatchBlock(typeof(Exception)); //临时变量 和 需要的反射信息 var exp = ilgen.DeclareLocal(typeof(Exception)); var msg = typeof(Exception).GetProperty("Message").GetGetMethod(); var output = typeof(Console).GetMethod("WriteLine",new Type[] { typeof(string),typeof(object) }); //保存异常对象到临时变量exp ilgen.Emit(OpCodes.Stloc,exp); //格式字符串进栈 ilgen.Emit(OpCodes.Ldstr,"错误信息: {0}"); //加载临时变量 ilgen.Emit(OpCodes.Ldloc,exp); //获取Message属性 ilgen.Emit(OpCodes.Callvirt,msg); //调用有格式字符串的Console.WriteLine ilgen.Emit(OpCodes.Call,output); //结束整个处理块 ilgen.EndExceptionBlock(); ilgen.Emit(OpCodes.Ret); return dm; } 输出: 复制代码 代码如下: 错误信息: 来自Mgen! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |