亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時間:2013年04月24日 14:34:21   作者:  
.NET(C#):Emit創(chuàng)建異常處理的方法,需要的朋友可以參考一下

目錄

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

復制代碼 代碼如下:

        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中的異常處理代碼還是比較復雜的,你可以在Reflector下看看異常處理的IL代碼。不過好在ILGenerator類提供了一些方便的方法來創(chuàng)建異常處理代碼。

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

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

來看代碼:

復制代碼 代碼如下:

        //+ 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塊");

             //結束整個處理塊

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

            //調用有格式字符串的Console.WriteLine

            ilgen.Emit(OpCodes.Call, output);

            //結束整個處理塊

            ilgen.EndExceptionBlock();

            ilgen.Emit(OpCodes.Ret);

            return dm;

        }


輸出:

復制代碼 代碼如下:

錯誤信息: 來自Mgen!

相關文章

  • Unity向量按照某一點進行旋轉

    Unity向量按照某一點進行旋轉

    這篇文章主要為大家詳細介紹了Unity向量按照某一點進行旋轉,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • C# SendMail發(fā)送郵件功能實現(xiàn)

    C# SendMail發(fā)送郵件功能實現(xiàn)

    這篇文章主要為大家詳細介紹了C# SendMail發(fā)送郵件功能實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • C#基礎知識之base關鍵字介紹

    C#基礎知識之base關鍵字介紹

    本文主要介紹base關鍵字的使用方法,base關鍵字可以調用基類重寫的方法,可以調用基類的構造方法,還可以在EntityFramework中使用,下面一一介紹。
    2016-04-04
  • C#中WebBrowser.DocumentCompleted事件多次調用問題解決方法

    C#中WebBrowser.DocumentCompleted事件多次調用問題解決方法

    這篇文章主要介紹了C#中WebBrowser.DocumentCompleted事件多次調用問題解決方法,本文講解了3種情況和各自情況的解決方法,需要的朋友可以參考下
    2015-01-01
  • C# BackgroundWorker組件學習入門介紹

    C# BackgroundWorker組件學習入門介紹

    一個程序中需要進行大量的運算,并且需要在運算過程中支持用戶一定的交互,為了獲得更好的用戶體驗,使用BackgroundWorker來完成這一功能
    2013-10-10
  • C# 注冊表 操作實現(xiàn)代碼

    C# 注冊表 操作實現(xiàn)代碼

    Windows 操作系統(tǒng)的注冊表包含了很多有關計算機運行的配置方式,打開注冊表我們可以看到注冊表是按類似于目錄的樹結構組織的
    2009-07-07
  • Task提高異步執(zhí)行效率技巧

    Task提高異步執(zhí)行效率技巧

    這篇文章介紹了Task提高異步執(zhí)行效率的技巧,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • 詳解C#的設計模式編程之抽象工廠模式的應用

    詳解C#的設計模式編程之抽象工廠模式的應用

    這篇文章主要介紹了C#的設計模式編程之抽象工廠模式的應用,注意區(qū)分一下簡單工廠模式、工廠方法模式和抽象工廠模式概念之間的區(qū)別,需要的朋友可以參考下
    2016-02-02
  • 深入理解C#指針之美

    深入理解C#指針之美

    在C#中,有時候希望通過指針來操作內存,這樣可以提高效率。我們可以用unsafe關鍵字修飾含有指針操作的程序段,感興趣的小伙伴可以參考一下,希望可以幫到你
    2021-07-07
  • C#循環(huán)與循環(huán)控制的表達式樹實現(xiàn)

    C#循環(huán)與循環(huán)控制的表達式樹實現(xiàn)

    這篇文章介紹了C#循環(huán)與循環(huán)控制的表達式樹實現(xiàn),文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01

最新評論