国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C#中標(biāo)準(zhǔn)Dispose模式的實(shí)現(xiàn)

2019-11-17 02:34:27
字體:
供稿:網(wǎng)友
C#中標(biāo)準(zhǔn)Dispose模式的實(shí)現(xiàn)

本文引自:[Luminji]http://m.survivalescaperooms.com/luminji/archive/2011/03/29/1997812.html

需要明確一下C#程序(或者說.NET)中的資源。簡(jiǎn)單的說來,C#中的每一個(gè)類型都代表一種資源,而資源又分為兩類:

托管資源:由CLR管理分配和釋放的資源,即由CLR里new出來的對(duì)象;

非托管資源:不受CLR管理的對(duì)象,windows內(nèi)核對(duì)象,如文件、數(shù)據(jù)庫(kù)連接、套接字、COM對(duì)象等;

毫無例外地,如果我們的類型使用到了非托管資源,或者需要顯式釋放的托管資源,那么,就需要讓類型繼承接口IDisposable。這相當(dāng)于是告訴調(diào)用者,該類型是需要顯式釋放資源的,你需要調(diào)用我的Dispose方法。

不過,這一切并不這么簡(jiǎn)單,一個(gè)標(biāo)準(zhǔn)的繼承了IDisposable接口的類型應(yīng)該像下面這樣去實(shí)現(xiàn)。這種實(shí)現(xiàn)我們稱之為Dispose模式:

復(fù)制代碼publicclass SampleClass : IDisposable { //演示創(chuàng)建一個(gè)非托管資源PRivate IntPtr nativeResource = Marshal.AllocHGlobal(100); //演示創(chuàng)建一個(gè)托管資源private AnotherResource managedResource =new AnotherResource(); privatebool disposed =false; ///<summary>/// 實(shí)現(xiàn)IDisposable中的Dispose方法 ///</summary>publicvoid Dispose() { //必須為true Dispose(true); //通知垃圾回收機(jī)制不再調(diào)用終結(jié)器(析構(gòu)器) GC.SuppressFinalize(this); } ///<summary>/// 不是必要的,提供一個(gè)Close方法僅僅是為了更符合其他語言(如C++)的規(guī)范 ///</summary>publicvoid Close() { Dispose(); } ///<summary>/// 必須,以備程序員忘記了顯式調(diào)用Dispose方法 ///</summary>~SampleClass() { //必須為false Dispose(false); } ///<summary>/// 非密封類修飾用protected virtual /// 密封類修飾用private ///</summary>///<param name="disposing"></param>protectedvirtualvoid Dispose(bool disposing) { if (disposed) { return; } if (disposing) { // 清理托管資源if (managedResource !=null) { managedResource.Dispose(); managedResource =null; } } // 清理非托管資源if (nativeResource != IntPtr.Zero) { Marshal.FreeHGlobal(nativeResource); nativeResource = IntPtr.Zero; } //讓類型知道自己已經(jīng)被釋放 disposed =true; } publicvoid SamplePublicMethod() { if (disposed) { thrownew ObjectDisposedException("SampleClass", "SampleClass is disposed"); } //省略 } }復(fù)制代碼

在Dispose模式中,幾乎每一行都有特殊的含義。

在標(biāo)準(zhǔn)的Dispose模式中,我們注意到一個(gè)以~開頭的方法:

復(fù)制代碼///<summary>/// 必須,以備程序員忘記了顯式調(diào)用Dispose方法 ///</summary>~SampleClass() { //必須為false Dispose(false); }復(fù)制代碼

這個(gè)方法叫做類型的終結(jié)器。提供終結(jié)器的全部意義在于:我們不能奢望類型的調(diào)用者肯定會(huì)主動(dòng)調(diào)用Dispose方法,基于終結(jié)器會(huì)被垃圾回收器調(diào)用這個(gè)特點(diǎn),終結(jié)器被用做資源釋放的補(bǔ)救措施。

一個(gè)類型的Dispose方法應(yīng)該允許被多次調(diào)用而不拋異常。鑒于這個(gè)原因,類型內(nèi)部維護(hù)了一個(gè)私有的布爾型變量disposed:

private bool disposed = false;

在實(shí)際處理代碼清理的方法中,加入了如下的判斷語句:

if (disposed) { return; } //省略清理部分的代碼,并在方法的最后為disposed賦值為true disposed =true;

這意味著類型如果被清理過一次,則清理工作將不再進(jìn)行。

應(yīng)該注意到:在標(biāo)準(zhǔn)的Dispose模式中,真正實(shí)現(xiàn)IDisposable接口的Dispose方法,并沒有實(shí)際的清理工作,它實(shí)際調(diào)用的是下面這個(gè)帶布爾參數(shù)的受保護(hù)的虛方法:

復(fù)制代碼///<summary>/// 非密封類修飾用protected virtual /// 密封類修飾用private ///</summary>///<param name="disposing"></param> protectedvirtualvoid Dispose(bool disposing) { //省略代碼 }復(fù)制代碼

之所以提供這樣一個(gè)受保護(hù)的虛方法,是為了考慮到這個(gè)類型會(huì)被其他類繼承的情況。如果類型存在一個(gè)子類,子類也許會(huì)實(shí)現(xiàn)自己的Dispose模式。受保護(hù)的虛方法用來提醒子類必須在實(shí)現(xiàn)自己的清理方法的時(shí)候注意到父類的清理工作,即子類需要在自己的釋放方法中調(diào)用base.Dispose方法。

還有,我們應(yīng)該已經(jīng)注意到了真正撰寫資源釋放代碼的那個(gè)虛方法是帶有一個(gè)布爾參數(shù)的。之所以提供這個(gè)參數(shù),是因?yàn)槲覀冊(cè)谫Y源釋放時(shí)要區(qū)別對(duì)待托管資源和非托管資源。

在供調(diào)用者調(diào)用的顯式釋放資源的無參Dispose方法中,調(diào)用參數(shù)是true:

publicvoid Dispose() { //必須為true Dispose(true); //其他省略 }

Word-break: normal; word-spacing: 0px; margin: 10px auto; letter-spacing: normal; line-height: 16px; background-color: #ffffff; text-indent: 0px; -webkit-text-stroke-w

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 时尚| 宜春市| 建湖县| 中阳县| 彭山县| 平塘县| 舟曲县| 万盛区| 罗源县| 尉犁县| 绵阳市| 铅山县| 八宿县| 宜丰县| 兴业县| 嫩江县| 收藏| 永川市| 大连市| 灌云县| 耒阳市| 永德县| 宁晋县| 宜宾市| 土默特右旗| 万年县| 合阳县| 华池县| 武乡县| 库伦旗| 论坛| 鄂托克前旗| 嘉义市| 忻城县| 远安县| 增城市| 莲花县| 祁连县| 镇康县| 甘肃省| 本溪市|