全面解讀C#編程中的析構(gòu)函數(shù)用法
析構(gòu)函數(shù)用于析構(gòu)類的實例。
備注
不能在結(jié)構(gòu)中定義析構(gòu)函數(shù)。只能對類使用析構(gòu)函數(shù)。
一個類只能有一個析構(gòu)函數(shù)。
無法繼承或重載析構(gòu)函數(shù)。
無法調(diào)用析構(gòu)函數(shù)。它們是被自動調(diào)用的。
析構(gòu)函數(shù)既沒有修飾符,也沒有參數(shù)。
例如,下面是類 Car 的析構(gòu)函數(shù)的聲明:
class Car
{
~Car() // destructor
{
// cleanup statements...
}
}
該析構(gòu)函數(shù)隱式地對對象的基類調(diào)用 Finalize。這樣,前面的析構(gòu)函數(shù)代碼被隱式地轉(zhuǎn)換為以下代碼:
protected override void Finalize()
{
try
{
// Cleanup statements...
}
finally
{
base.Finalize();
}
}
這意味著對繼承鏈中的所有實例遞歸地調(diào)用 Finalize 方法(從派生程度最大的到派生程度最小的)。
注意
不應(yīng)使用空析構(gòu)函數(shù)。如果類包含析構(gòu)函數(shù),F(xiàn)inalize 隊列中則會創(chuàng)建一個項。調(diào)用析構(gòu)函數(shù)時,將調(diào)用垃圾回收器來處理該隊列。如果析構(gòu)函數(shù)為空,只會導(dǎo)致不必要的性能損失。
程序員無法控制何時調(diào)用析構(gòu)函數(shù),因為這是由垃圾回收器決定的。垃圾回收器檢查是否存在應(yīng)用程序不再使用的對象。如果垃圾回收器認為某個對象符合析構(gòu),則調(diào)用析構(gòu)函數(shù)(如果有)并回收用來存儲此對象的內(nèi)存。程序退出時也會調(diào)用析構(gòu)函數(shù)。
可以通過調(diào)用 Collect 強制進行垃圾回收,但大多數(shù)情況下應(yīng)避免這樣做,因為這樣會導(dǎo)致性能問題。
使用析構(gòu)函數(shù)釋放資源
通常,與運行時不進行垃圾回收的開發(fā)語言相比,C# 無需太多的內(nèi)存管理。這是因為 .NET Framework 垃圾回收器會隱式地管理對象的內(nèi)存分配和釋放。但是,當應(yīng)用程序封裝窗口、文件和網(wǎng)絡(luò)連接這類非托管資源時,應(yīng)當使用析構(gòu)函數(shù)釋放這些資源。當對象符合析構(gòu)時,垃圾回收器將運行對象的 Finalize 方法。
資源的顯式釋放
如果您的應(yīng)用程序在使用昂貴的外部資源,我們還建議您提供一種在垃圾回收器釋放對象前顯式地釋放資源的方式??赏ㄟ^實現(xiàn)來自 IDisposable 接口的 Dispose 方法來完成這一點,該方法為對象執(zhí)行必要的清理。這樣可大大提高應(yīng)用程序的性能。即使有這種對資源的顯式控制,析構(gòu)函數(shù)也是一種保護措施,可用來在對 Dispose 方法的調(diào)用失敗時清理資源。
下面的示例創(chuàng)建三個類,這三個類構(gòu)成了一個繼承鏈。類 First 是基類,Second 是從 First 派生的,而 Third 是從 Second 派生的。這三個類都有析構(gòu)函數(shù)。在 Main() 中,創(chuàng)建了派生程度最大的類的實例。注意:程序運行時,這三個類的析構(gòu)函數(shù)將自動被調(diào)用,并且是按照從派生程度最大的到派生程度最小的次序調(diào)用。
class First
{
~First()
{
System.Diagnostics.Trace.WriteLine("First's destructor is called.");
}
}
class Second : First
{
~Second()
{
System.Diagnostics.Trace.WriteLine("Second's destructor is called.");
}
}
class Third : Second
{
~Third()
{
System.Diagnostics.Trace.WriteLine("Third's destructor is called.");
}
}
class TestDestructors
{
static void Main()
{
Third t = new Third();
}
}
輸出:
Third's destructor is called. Second's destructor is called. First's destructor is called.
析構(gòu)函數(shù)與Dispose()方法的區(qū)別
1. Dispose需要實現(xiàn)IDisposable接口。
2. Dispose由開發(fā)人員代碼調(diào)用,而析構(gòu)函數(shù)由GC自動調(diào)用。
3. Dispose方法應(yīng)釋放所有托管和非托管資源。而析構(gòu)函數(shù)只應(yīng)釋放非托管資源。因為析構(gòu)函數(shù)由GC來判斷調(diào)用,當GC判斷某個對象不再需要的時候,則調(diào)用其析構(gòu)方法,這時候該對象中可能還包含有其他有用的托管資源。
4. 通過系統(tǒng)GC頻繁的調(diào)用析構(gòu)方法來釋放資源會降低系統(tǒng)性能,所以推薦顯示調(diào)用Dispose方法。
5. Dispose方法結(jié)尾處加上代碼“GC.SuppressFinalize(this);”,即告訴GC不需要再調(diào)用該對象的析構(gòu)方法,否則,GC仍會在判斷該對象不再有用后調(diào)用其析構(gòu)方法,雖然程序不會出錯,但影響系統(tǒng)性能。
6、析構(gòu)函數(shù) 和 Dispose 釋放的資源應(yīng)該相同,這樣即使類使用者在沒有調(diào)用 Dispose 的情況下,資源也會在 Finalize 中得到釋放。
7、Finalize 不應(yīng)為 public。
8、有 Dispose 方法存在時,應(yīng)該調(diào)用它,因為 Finalize 釋放資源通常是很慢的。
上一篇:解析C#面向?qū)ο缶幊讨蟹椒ǎ╩ethod)的使用
欄 目:C#教程
本文標題:全面解讀C#編程中的析構(gòu)函數(shù)用法
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/6731.html
您可能感興趣的文章
- 01-10C#編程實現(xiàn)自定義熱鍵的方法
- 01-10C#編程獲取資源文件中圖片的方法
- 01-10C#編程自學(xué)之數(shù)據(jù)類型和變量二
- 01-10C#編程自學(xué)之開篇介紹
- 01-10C#編程自學(xué)之數(shù)據(jù)類型和變量三
- 01-10C#編程自學(xué)之運算符和表達式
- 01-10C#編程自學(xué)之類和對象
- 01-10C#編程和Visual Studio使用技巧(下)
- 01-10C#編程自學(xué)之數(shù)據(jù)類型和變量一
- 01-10C#編程和Visual Studio使用技巧(上)


閱讀排行
本欄相關(guān)
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻播放器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10delphi制作wav文件的方法
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10C#中split用法實例總結(jié)
- 08-05DEDE織夢data目錄下的sessions文件夾有什


