析構函數、dispose模式

析構函數書寫規則

在C#3.0發佈之前,析構函數有時也叫終結器(finalizer)
(1)每個類只能有一個析構函數
(2)析構函數不能有參數
(3)析構函數不能有訪問修飾符
(4)析構函數名稱與類名相同,但要在前面加一個~
(5)析構函數只能作用與類的實例,因此沒有靜態析構函數
(6)不能在代碼中顯式調用析構函數,相反,當垃圾回收器分析代碼並認爲代碼中不存在指向該對象的可能路徑時,系統會在垃圾回收過程中調用析構函數。

    public class A
    {
        ~A()   //析構函數
        {
            //相關釋放處理
        }
    }

析構函數的使用規則

(1)不要在不需要時實現析構函數,這會嚴重影響性能
(2)析構函數應該只釋放對象擁有的外部資源
(3)析構函數不應該訪問其他對象,因爲無法認定這些對象是否已經被銷燬

標準dispose模式

與C++析構函數不同,C#析構函數不會在實例超出作用域時立即調用,事實上,你無法知道何時會調用析構函數,而且你也不能顯式調用析構函數,你所能知道的只是,系統會在對象從託管堆上移除之前的某個時刻調用析構函數。如果你想讓你的代碼中包含的非託管資源越快釋放越好,就不能將這個任務留給析構函數,因爲無法保證它會何時執行,這時應該採用標準dispose模式

標準dispose模式使用規則

(1)包含非託管資源的類應該實現IDisposable接口,該接口包含單一方法Dispose,Dispose包含釋放資源的清除代碼。
(2)如果代碼使用完了這些資源並且希望將它們釋放,應該在程序代碼中調用Dispose方法,注意這是在你的代碼中(不是系統中)調用Dispose。
(3)你的類還應該實現一個析構函數,在其中調用Dispose方法,以防止之前沒有調用該方法。但是如果調用了Dispose,就需要通知垃圾回收器不要再調用析構函數,因爲已經由Dispose執行了清除操作。

析構函數和Disposed代碼應遵守的規則

(1)倆者的邏輯應該是,如果由於某種原因代碼沒有調用Dispose,那麼析構函數應該調用它,並釋放資源
(2)在public版本的Dispose方法的最後應該調用GC.SuppressFinalize方法通知CLR不要調用該對象的析構函數,因爲清除工作已經完成。
(3)在Dispose中實現的這些代碼,經過多次調用也應該是安全的,也就是說這個方法已經被調用過一次後,後續的調用不會執行額外的工作,也不會拋出任何異常。
(4)Dispose方法有倆個重載,一個是public的,一個是protected的,protected的重載包含實際的清除代碼
(5)public版本可以在代碼中顯式調用來執行清除工作,它會在內部調用protected版本
(6)析構函數調用的是protected版本
(7)protected版本的bool參數通知方法是被析構函數或是其他代碼調用,這一點很重要,因爲結果不同所執行的操作會略有不同。

析構函數與構造函數

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