【.net 深呼吸】細說CodeDom(10):生成異常處理語句

weixin_34088583發表於2017-01-17

寫完這一篇,大概可以準備過年了,就算是這系列文章的收尾吧。

異常處理語句,就是常說的try...catch語句,有時候,也會帶有finally子句。要生成異常處理語句,得用到CodeTryCatchFinallyStatement類,它包含三個部分。

1、TryStatements:嘗試執行的程式碼塊。

2、CatchClauses:捕捉異常的程式碼塊。CatchClauses是一個子句集合,因為一個try語句可以包含N個catch子句,而每個catch塊都由CodeCatchClause類來表示,使用時應提供要捕捉的異常的型別,異常物件的臨時變數名,以及catch塊的語句集合。

3、FinallyStatements:finally語句塊,不管會不會發生異常,finally中的語句會執行。

 

下面看一個最常見的try語句的生成。

            CodeTryCatchFinallyStatement trycatfanStatement = new CodeTryCatchFinallyStatement();
            trycatfanStatement.TryStatements.Add(new CodeCommentStatement("試著執行"));
            CodeCatchClause catClause = new CodeCatchClause();
            // 異常型別
            catClause.CatchExceptionType = new CodeTypeReference(typeof(Exception));
            // 臨時變數名
            catClause.LocalName = "ex";
            // catch塊中的語句
            catClause.Statements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(Console)), nameof(Console.WriteLine)), new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("ex"), nameof(Exception.Message))));
            // 記得將 CodeCatchClause 物件加入到 CatchClauses 集合中
            trycatfanStatement.CatchClauses.Add(catClause);

            CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
            provider.GenerateCodeFromStatement(trycatfanStatement, Console.Out, null);

以上程式碼只生成了try和catch兩個子塊,這種形式是最為常見的。其生成的程式碼如下。

 

當然,如果需要,還可以新增上 finally 塊,在上面的示例程式碼中加入以下程式碼:

            trycatfanStatement.FinallyStatements.Add(new CodeCommentStatement("清理操作"));

然後生成的程式碼中就會包含 finally 塊了。

 

try 語句可以包括多個 catch 子句,比如這樣。

            CodeTryCatchFinallyStatement trystatement = new CodeTryCatchFinallyStatement();
            trystatement.TryStatements.Add(new CodeCommentStatement("待執行程式碼"));
            // 第一個 catch 子句
            CodeCatchClause catch1 = new CodeCatchClause();
            catch1.CatchExceptionType = new CodeTypeReference(typeof(FormatException));
            catch1.LocalName = "fex";
            catch1.Statements.Add(new CodeCommentStatement("捕捉異常"));
            trystatement.CatchClauses.Add(catch1);
            // 第二個 catch 子句
            CodeCatchClause catch2 = new CodeCatchClause();
            catch2.CatchExceptionType = new CodeTypeReference(typeof(ArgumentException));
            catch2.LocalName = "gex";
            catch2.Statements.Add(new CodeCommentStatement("捕捉異常"));
            trystatement.CatchClauses.Add(catch2);

            CodeDomProvider p = CodeDomProvider.CreateProvider("C#");
            p.GenerateCodeFromStatement(trystatement, Console.Out, null);

以上程式碼生成的try語句包含兩個catch子句,分別捕捉FormatException和ArgumentException兩種型別的異常。生成的程式碼如下。

 

 

順便也說說丟擲異常的語句,使用的是 CodeThrowExceptionStatement 類,例如

            CodeThrowExceptionStatement ts = new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(FieldAccessException)));

生成的throw語句如下圖所示。

傳遞給 CodeThrowExceptionStatement 建構函式的引數為要丟擲的異常物件,本例直接用new關鍵字來建立異常例項。如果明確定義了異常變數,可以引用變數。就像這樣。

            CodeVariableDeclarationStatement vd = new CodeVariableDeclarationStatement(typeof(EncoderFallbackException), "ex", new CodeObjectCreateExpression(typeof(EncoderFallbackException)));
            CodeThrowExceptionStatement ts = new CodeThrowExceptionStatement(new CodeVariableReferenceExpression("ex"));

            CodeDomProvider p = CodeDomProvider.CreateProvider("cs");
            p.GenerateCodeFromStatement(vd, Console.Out, null);
            p.GenerateCodeFromStatement(ts, Console.Out, null);

生成的程式碼如下。

 

 ===========================================

好了,Code DOM 系列文章就寫完了。

 

過年後,如果能趕上 Windows 10 “紅石2”的更新,那我們們就繼續聊 UWP 相關的內容。

提前祝大夥新春快樂。

 

相關文章