原文地址:http://www./csharpspace/8927r1397.shtml MSDN建議按照下面的模式實(shí)現(xiàn)IDisposable接口: ![]() 1 public class Foo: IDisposable 2 { 3 public void Dispose() 4 { 5 Dispose(true); 6 GC.SuppressFinalize(this); 7 } 8 9 protected virtual void Dispose(bool disposing) 10 { 11 if (!m_disposed) 12 { 13 if (disposing) 14 { 15 // Release managed resources 16 } 17 // Release unmanaged resources 18 m_disposed = true; 19 } 20 } 21 22 ~Foo() 23 { 24 Dispose(false); 25 } 26 private bool m_disposed; 27 } ![]() ? 在.NET的對(duì)象中實(shí)際上有兩個(gè)用于釋放資源的函數(shù):Dispose和Finalize。Finalize的目的是用于釋放非托管的資源,而Dispose是用于釋放所有資源,包括托管的和非托管的。 在這個(gè)模式中,void Dispose(bool disposing)函數(shù)通過一個(gè)disposing參數(shù)來(lái)區(qū)別當(dāng)前是否是被Dispose()調(diào)用。如果是被Dispose()調(diào)用,那么需要同時(shí)釋放 托管和非托管的資源。如果是被~Foo()(也就是C#的Finalize())調(diào)用了,那么只需要釋放非托管的資源即可。 這是因?yàn)?,Dispose()函數(shù)是被其它代碼顯式調(diào)用并要求釋放資源的,而Finalize是被GC調(diào)用的。在GC調(diào)用的時(shí)候Foo所引用的其它 托管對(duì)象可能還不需要被銷毀,并且即使要銷毀,也會(huì)由GC來(lái)調(diào)用。因此在Finalize中只需要釋放非托管資源即可。另外一方面,由于在 Dispose()中已經(jīng)釋放了托管和非托管的資源,因此在對(duì)象被GC回收時(shí)再次調(diào)用Finalize是沒有必要的,所以在Dispose()中調(diào)用 GC.SuppressFinalize(this)避免重復(fù)調(diào)用Finalize。 然而,即使重復(fù)調(diào)用Finalize和Dispose也是不存在問題的,因?yàn)橛凶兞縨_disposed的存在,資源只會(huì)被釋放一次,多余的調(diào)用會(huì)被忽略過去。 因此,上面的模式保證了: 1、 Finalize只釋放非托管資源; 2、 Dispose釋放托管和非托管資源; 3、 重復(fù)調(diào)用Finalize和Dispose是沒有問題的; 4、 Finalize和Dispose共享相同的資源釋放策略,因此他們之間也是沒有沖突的。 在C#中,這個(gè)模式需要顯式地實(shí)現(xiàn),其中C#的~Foo()函數(shù)代表了Finalize()。而在C /CLI中,這個(gè)模式是自動(dòng)實(shí)現(xiàn)的,C 的類析構(gòu)函數(shù)則是不一樣的。 按照C 語(yǔ)義,析構(gòu)函數(shù)在超出作用域,或者delete的時(shí)候被調(diào)用。在Managed C (即.NET 1.1中的托管C )中,析構(gòu)函數(shù)相當(dāng)于CLR中的Finalize()方法,在垃圾收集的時(shí)候由GC調(diào)用,因此,調(diào)用的時(shí)機(jī)是不明確的。在.NET 2.0的C /CLI中,析構(gòu)函數(shù)的語(yǔ)義被修改為等價(jià)與Dispose()方法,這就隱含了兩件事情: 1、 所有的C /CLI中的CLR類都實(shí)現(xiàn)了接口IDisposable,因此在C#中可以用using關(guān)鍵字來(lái)訪問這個(gè)類的實(shí)例。 2、 析構(gòu)函數(shù)不再等價(jià)于Finalize()了。 ? ----------------------------------以下是CSDN上一位高手的總結(jié)---------------------------------------------- 1、Finalize方法(C#中是析構(gòu)函數(shù),以下稱析構(gòu)函數(shù))是用于釋放非托管資源的,而托管資源會(huì)由GC自動(dòng)回收。所以,我們也可以這樣來(lái)區(qū)分 托管和非托管資源。所有會(huì)由GC自動(dòng)回收的資源,就是托管的資源,而不能由GC自動(dòng)回收的資源,就是非托管資源。在我們的類中直接使用非托管資源的情況很 少,所以基本上不用我們寫析構(gòu)函數(shù)。? |
|