【轉】編寫高品質代碼改善C#程式的157個建議——建議46:顯式釋放資源需繼承介面IDisposable

來源:互聯網
上載者:User

標籤:man   prot   style   public   ++   ==   ret   span   source   

 

建議46:顯式釋放資源需繼承介面IDisposable

C#中的每一個類型都代表一種資源,資源分為兩類:

託管資源:由CLR管理分配和釋放的資源,即從CLR裡new出來的對象。

非託管資源:不受CLR管理的對象,如Windows核心對象,或者檔案、資料庫連接、通訊端、COOM對象等。

如果我們的類型使用了非託管資源,或者需要顯示地釋放託管資源,那麼就需要讓類型繼承介面IDisposable,這毫無例外。這相當於告訴調用者,類型資源是需要顯示釋放資源的,你需要調用類型的Dispose方法。

 

一個標準的繼承了IDisposable介面的類型應該像下面這樣去實現,這種實現我們稱為Dispose模式:

    public class SampleClass : IDisposable    {        //示範建立一個非託管資源        private IntPtr nativeResource = Marshal.AllocHGlobal(100);        //示範建立一個託管資源        private AnotherResource managedResource = new AnotherResource();        private bool disposed = false;        /// <summary>        /// 實現IDisposable中的Dispose方法        /// </summary>        public void Dispose()        {            //必須為true            Dispose(true);            //通知記憶體回收機制不再調用終結器(析構器)            GC.SuppressFinalize(this);        }        /// <summary>        /// 不是必要的,提供一個Close方法僅僅是為了更符合其他語言(如        /// C++)的規範        /// </summary>        public void Close()        {            Dispose();        }        /// <summary>        /// 必須,防止程式員忘記了顯式調用Dispose方法        /// </summary>        ~SampleClass()        {            //必須為false            Dispose(false);        }        /// <summary>        /// 非密封類修飾用protected virtual        /// 密封類修飾用private        /// </summary>        /// <param name="disposing"></param>        protected virtual void 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;            }            //讓類型知道自己已經被釋放            disposed = true;        }        public void SamplePublicMethod()        {            if (disposed)            {                throw new ObjectDisposedException("SampleClass", "SampleClass is disposed");            }            //省略        }    }    class AnotherResource : IDisposable    {        public void Dispose()        {        }    }

繼承IDisposable介面也為實現文法糖using帶來了便利。如:

using (SampleClass cl = new SampleClass()){    //省略}

等價於:

SampleClass cl;try{    cl == new SampleClass();    //省略}finally{    cl.Dispose();}

如果存在兩個類型一致的對象,using還可以這樣使用:

using (SampleClass c1 = new SampleClass(),c2=new SampleClass()){  //省略}

如果兩個類型不一致,則可以這樣使用:

using (SampleClass c1 = new SampleClass())using (SampleAnotherClass c2 = new SampleAnotherClass()){    //省略}

 

 

 

 

轉自:《編寫高品質代碼改善C#程式的157個建議》陸敏技

【轉】編寫高品質代碼改善C#程式的157個建議——建議46:顯式釋放資源需繼承介面IDisposable

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.