簡體   English   中英

finally 塊下面的代碼如何執行?

[英]How code below the finally block execute?

我找不到任何微軟官方資源來顯示 finally 塊下面的代碼是如何執行的,關於它的唯一信息是通過 C# 的書 CLR,作者說:

如果在 try 塊中沒有拋出異常,或者如果 catch 塊捕獲到異常並且不拋出或重新拋出異常,則 finally 塊下面的代碼將執行。

假設我們有以下代碼:

class Program {
   static void Main(string[] args) {
      SomeMethod1();
      Console.ReadLine();
   }

   static void SomeMethod1() {
      try {
         SomeMethod2();
      }
      finally {
         Console.WriteLine("SomeMethod1 finally");
      }
      Console.WriteLine("SomeMethod1 last");
   }

   static void SomeMethod2() {
      try {
         SomeMethod3();
      }
      catch (DivideByZeroException e) {
         Console.WriteLine("SomeMethod2 caught");
      }
      finally {
         Console.WriteLine("SomeMethod2 finally");
      }
      Console.WriteLine("SomeMethod2 last");
   }

   static void SomeMethod3() {
      try {
         SomeMethod4();
      }
      finally {
         Console.WriteLine("SomeMethod3 finally");
      }
      Console.WriteLine("SomeMethod3 last");
   }

   static void SomeMethod4() {
      try {
         Int32 i = 0;
         var c = 3 / i;
      }
      finally {
         Console.WriteLine("SomeMethod4 finally");
      }
      Console.WriteLine("SomeMethod4 last");
   }
}

output 是:

SomeMethod4 finally
SomeMethod3 finally
SomeMethod2 caught
SomeMethod2 finally
SomeMethod2 last
SomeMethod1 finally
SomeMethod1 last

您可以看到“SomeMethod4 last”和“SomeMethod3 last”沒有被打印出來。 “SomeMethod4 last”不被打印好理解,因為SomeMethod4拋出了異常,並且沒有catch塊來捕獲異常,所以不符合作者規定的要求,還算公道。

但是為什么“SomeMethod3 last”沒有被打印出來? SomeMethod3沒有拋出異常,就像SomeMethod1一樣,那么為什么“SomeMethod1 last”被打印而“SomeMethod3 last”沒有? 是否有任何 Microsoft 官方資源可以解釋其機制?

當在SomeMethod4中引發異常時,它會向上流向調用方法SomeMethod3 把它想象成SomeMethod4實際上像這樣內聯在SomeMethod3中。

    static void SomeMethod3()
    {
        try
        {
            try
            {
                Int32 i = 0;
                var c = 3 / i;
            }
            finally
            {
                Console.WriteLine("SomeMethod4 finally");
            }
            Console.WriteLine("SomeMethod4 last");
        }
        finally
        {
            Console.WriteLine("SomeMethod3 finally");
        }
        Console.WriteLine("SomeMethod3 last");
    }

SomeMethod2 Last 運行的原因是因為它是實際捕獲異常的部分。

如果您向SomeMethod3添加一個 catch ,您將看到SomeMethod3 Last也被打印出來。

異常會中斷應用程序的流程,並且在到達 catch 語句之前基本上不會停止返回調用堆棧。 從技術上講,異常是在SomeMethod1中引發的,但它在SomeMethod2中被捕獲,這意味着異常永遠不會到達SomeMethod1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM