a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C# > 正文

.NET(C#):Emit創(chuàng)建異常處理的方法

2020-01-24 03:26:17
字體:
供稿:網(wǎng)友

目錄

Emit異常處理流程
顯示Exception對象的Message屬性
返回目錄
Emit異常處理流程
來看這種C#異常處理代碼:

復(fù)制代碼 代碼如下:

        static void doo(Exception e)

        {

            try

            {

                throw e;

            }

            catch (ApplicationException ex)

            {

                Console.WriteLine("捕獲ApplicationException");

            }

            catch

            {

                Console.WriteLine("捕獲Exception");

            }

            finally

            {

                Console.WriteLine("finally塊");

            }

        }

我們將用反射Emit創(chuàng)建一個這樣的方法。

其實IL中的異常處理代碼還是比較復(fù)雜的,你可以在Reflector下看看異常處理的IL代碼。不過好在ILGenerator類提供了一些方便的方法來創(chuàng)建異常處理代碼。

基本套路就是用如下ILGenerator的方法:

BeginExceptionBlock方法來開始異常處理代碼(相當(dāng)于try)。
之后的代碼可以用Opcodes.Throw來拋出異常,或者調(diào)用其他可以拋出異常的代碼。
接著用BeginCatchBlock方法來開始一個Catch塊,該方法可以指定catch需要捕獲的異常類型,另外有一點需要注意的是凡是進入該catch方法,邏輯棧上會有相應(yīng)類型的異常對象。 同時,這里也可以用Opcodes.Rethrow來重新拋出異常。
最后BeginFinallyBlock方法開始一個finally塊。 (這里不需要手動加Opcodes.Leave)
當(dāng)全部異常處理代碼寫完后,加上EndExceptionBlock方法來結(jié)束整塊異常處理代碼塊。
注意方法最后還是必須要加IL的ret指令的(Opcodes.Ret),否則CLR無法運行此方法。

來看代碼:

復(fù)制代碼 代碼如下:

        //+ using System.Reflection;

        //+ using System.Reflection.Emit;

        static void Main(string[] args)
        {
            var dm = GetMethod();

            dm.Invoke(null, new object[] { new ApplicationException() });

            dm.Invoke(null, new object[] { new Exception() });

        }
        static DynamicMethod GetMethod()

        {

            var dm = new DynamicMethod("", null, new Type[] { typeof(Exception) });

            var ilgen = dm.GetILGenerator();

            //try {

            ilgen.BeginExceptionBlock();

            //加載第一個參數(shù),并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塊");

             //結(jié)束整個處理塊

            ilgen.EndExceptionBlock();

            ilgen.Emit(OpCodes.Ret);

            return dm;

        }

輸出:

復(fù)制代碼 代碼如下:

捕獲ApplicationException

finally塊

捕獲Exception

finally塊


返回目錄
顯示Exception對象的Message屬性
上面的代碼并沒有顯示Exception對象的Message屬性,上面主要是介紹Emit異常處理的流程,下面來看看怎樣顯示Message屬性,如果是直接輸出當(dāng)然簡單了,不過如果用到Console.WriteLine的格式字符串的話,需要在catch代碼塊中用一個臨時變量。

如下代碼:

復(fù)制代碼 代碼如下:

        //+ using System.Reflection;

        //+ using System.Reflection.Emit;
        static void Main(string[] args)
        {
            var dm = GetMethod();

            dm.Invoke(null, new object[] { new Exception("來自Mgen!") });
        }

        static DynamicMethod GetMethod()
        {

            var dm = new DynamicMethod("", null, new Type[] { typeof(Exception) });

            var ilgen = dm.GetILGenerator();

            //try {

            ilgen.BeginExceptionBlock();

            //加載第一個參數(shù),并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);

            //調(diào)用有格式字符串的Console.WriteLine

            ilgen.Emit(OpCodes.Call, output);

            //結(jié)束整個處理塊

            ilgen.EndExceptionBlock();

            ilgen.Emit(OpCodes.Ret);

            return dm;

        }


輸出:

復(fù)制代碼 代碼如下:

錯誤信息: 來自Mgen!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美日韩在线视频一区 | 国产精品视频一区二区三区麻豆 | 青青草原国产在线 | 国产在线一区二区三区视频 | 日韩国产一区二区三区 | av网站在线免费观看 | 99re国产 | 草草在线观看 | 亚洲精品一区二区网址 | 久久av一区二区 | 久久精品性 | 亚洲午夜在线 | 3bmm在线观看视频免费 | 亚洲天天 | 91精品国产乱码久久蜜臀 | 中文字幕亚洲欧美 | 日韩在线视频二区 | 亚洲最黄视频 | 亚洲欧美日韩另类精品一区二区三区 | 99精品网站| 97国产精品| 草久在线视频 | 一级特黄网站 | 久久免费看 | 日韩精品在线视频 | 国产精品一区二区三区四区 | 亚洲综合在线一区二区 | 欧美日韩成人在线观看 | 日韩av在线电影 | 久久精品视 | 精品欧美一区二区在线观看 | 国产99久久精品一区二区永久免费 | 色综合天天综合网国产成人网 | 香蕉大人久久国产成人av | 国产精品国产三级国产aⅴ中文 | 精品亚洲视频在线观看 | 日韩专区在线播放 | 国产精品一区二 | 精品欧美一区二区在线观看视频 | 亚洲精品www久久久久久 | 综合91|