dotnet C# 如果在構造函數拋出異常 析構函數是否會執行

假設在某個類型的構造函數裏面拋出了異常,那麼這個對象的析構函數是否會執行

如下面代碼

        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 運行時,是先創建出對象,然後再調用對象的構造函數。而在創建出對象時,此對象就需要被加入垃圾回收,加入垃圾回收,自然就會調用到析構函數

那爲什麼即使在構造函數裏面拋出異常,沒有構造成功,也需要在垃圾回收調用析構函數。是因爲構造函數也不一定是一句話都沒有跑的,例如在構造函數裏面已分配了一些非託管的內存,然後再拋出異常,自然就期望在析構函數可以釋放分配的內存,也就是期望調用析構函數

本文代碼還請到 githubgitee 上閱讀代碼

可以通過如下方式獲取本文的源代碼,先創建一個空文件夾,接着使用命令行 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 文件夾

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章