假設在某個類型的構造函數裏面拋出了異常,那麼這個對象的析構函數是否會執行
如下面代碼
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 運行時,是先創建出對象,然後再調用對象的構造函數。而在創建出對象時,此對象就需要被加入垃圾回收,加入垃圾回收,自然就會調用到析構函數
那爲什麼即使在構造函數裏面拋出異常,沒有構造成功,也需要在垃圾回收調用析構函數。是因爲構造函數也不一定是一句話都沒有跑的,例如在構造函數裏面已分配了一些非託管的內存,然後再拋出異常,自然就期望在析構函數可以釋放分配的內存,也就是期望調用析構函數
可以通過如下方式獲取本文的源代碼,先創建一個空文件夾,接着使用命令行 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 文件夾