析構函數是通過下面的形式聲明的:
[attributes] ~ identifier( ) { destructor-body }
其中:
attributes(可選)
附加的聲明性信息。有關屬性和屬性類的更多信息,請參見 C# 屬性。
identifier
identifier 與類名相同。
destructor-body
包含銷毀類實例的語句的塊。
備注
不能對結構使用析構函數。只能對類使用析構函數。
一個類只能有一個析構函數。
無法繼承或重載析構函數。
無法調用析構函數。它們是被自動調用的。
析構函數既沒有修飾符,也沒有參數。例如,下面是類 MyClass 的析構函數的聲明:
~ MyClass() { // Cleanup statements.}
該析構函數隱式地對對象的基類調用 Object.Finalize 方法。這樣,前面的析構函數代碼被隱式地轉換為:
protected override void Finalize(){ try { // Cleanup statements. } finally { base.Finalize(); }}
這意味著對繼承鏈中的所有實例遞歸地(從派生相近程度最大的到派生相近程度最小的)調用 Finalize 方法。
程序員無法控制何時調用析構函數,因為這由垃圾回收器決定的。垃圾回收器檢查是否存在應用程序不再使用的對象。它認為這些對象符合銷毀條件並回收這些對象占用的內存。程序退出時也會調用析構函數。
可以通過調用 GC.Collect 方法強制進行垃圾回收,但大多數情況下應避免這樣做,因為這樣會導致出現性能問題。有關更多信息,請參見強制垃圾回收。
示例
下面的示例創建三個類,這三個類構成了一個繼承鏈。類 First 是基類,Second 是從 First 派生的,而 Third 是從 Second 派生的。這三個類都有析構函數。在 Main() 中,創建了派生相近程度最大的類的實例。程序運行時,注意這三個類的析構函數會自動被調用,並且是按照從派生相近程度最大的到派生相近程度最小的次序調用。
// Destructors1.csusing System;class First{ ~First() { Console.WriteLine("First’s destructor is called"); }}class Second: First{ ~Second() { Console.WriteLine("Second’s destructor is called"); }}class Third: Second{ ~Third() { Console.WriteLine("Third’s destructor is called"); }}public class MainClass { public static void Main() { Third myObject = new Third(); }}
輸出
Third’s destructor is calledSecond’s destructor is calledFirst’s destructor is called
使用析構函數釋放資源
一般來說,您不必像使用 C 時那樣關注內存管理。這是因為 .NET Framework 垃圾回收器會隱式地管理對象的內存分配和釋放。但是,當應用程序封裝窗口、文件和網絡連接這類非托管資源時,應當使用析構函數釋放這些資源。當對象符合銷毀條件時,垃圾回收器會運行對象的 Finalize 方法。
資源的顯式釋放
如果您的應用程序在使用昂貴的外部資源,則還建議您提供一種在垃圾回收器釋放對象前顯式地釋放資源的方式。可通過實現 Dispose 方法(來自 IDisposable 接口)來完成這一點,該方法為對象執行必要的清理。這樣可大大提高應用程序的性能。即使有這種對資源的顯式控制,析構函數也是一種保護措施,可用來在對 Dispose 方法的調用失敗時清理資源。