dotnet C# 如果在建構函式丟擲異常 解構函式是否會執行
阿新 • • 發佈:2021-06-17
假設在某個型別的建構函式裡面丟擲了異常,那麼這個物件的解構函式是否會執行
如下面程式碼
private void F1() { try { _ = new Foo(); } catch { // 忽略 } } class Foo { public Foo() { throw new Exception("lindexi is doubi"); } ~Foo() { } }
請問以上程式碼的 ~Foo
是否可以在垃圾回收執行,或者說在建構函式裡面丟擲異常,是否這個物件可以被垃圾回收
試試以下程式碼,然後在 ~Foo
新增斷點
static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; var program = new Program(); program.F1(); GC.Collect(); GC.WaitForFullGCComplete(); GC.Collect(); Task.Delay(1000).Wait(); Console.WriteLine("Hello World!"); }
其實可以看到,可以進入 ~Foo
的程式碼。原因是在 .NET 執行時,是先創建出物件,然後再呼叫物件的建構函式。而在創建出物件時,此物件就需要被加入垃圾回收,加入垃圾回收,自然就會呼叫到解構函式
那為什麼即使在建構函式裡面丟擲異常,沒有構造成功,也需要在垃圾回收呼叫解構函式。是因為建構函式也不一定是一句話都沒有跑的,例如在建構函式裡面已分配了一些非託管的記憶體,然後再丟擲異常,自然就期望在解構函式可以釋放分配的記憶體,也就是期望呼叫解構函式
本文程式碼還請到 github 或 gitee 上閱讀程式碼
可以通過如下方式獲取本文的原始碼,先建立一個空資料夾,接著使用命令列 cd 命令進入此空資料夾,在命令列裡面輸入以下程式碼,即可獲取到本文的程式碼
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 3f16a1492f1d655ad5356e65d476c3c91b129844
以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
獲取程式碼之後,進入 HojeneceabuHallwhallhebo 資料夾