C++編程人員容易犯的10個C#錯誤2

字號:

錯誤2:Finalize和Dispose使用誰?
    從上面的論述中我們已經(jīng)很清楚,顯性地調(diào)用finalizer是不允許的,它只能被碎片收集程序調(diào)用。如果希望盡快地釋放一些不再使用的數(shù)量有限的非可管理性資源(如文件句柄),則應(yīng)該使用IDisposable界面,這一界面有個Dispose方法,它能夠幫你完成這個任務(wù)。Dispose是無需等待Finalize被調(diào)用而能夠釋放非可管理性資源的方法。
    如果已經(jīng)使用了Dispose方法,則應(yīng)當阻止碎片收集程序再對相應(yīng)的對象執(zhí)行Finalize方法。為此,需要調(diào)用靜態(tài)方法GC.SuppressFinalize,并將相應(yīng)對象的指針傳遞給它作為參數(shù),F(xiàn)inalize方法就能調(diào)用Dispose方法了。據(jù)此,我們能夠得到如下的代碼:
    public void Dispose()
    {
    // 完成清理操作
    // 通知GC不要再調(diào)用Finalize方法
    GC.SuppressFinalize(this);
    }
    public override void Finalize()
    {
    Dispose();
    base.Finalize();
    }
    對于有些對象,可能調(diào)用Close方法就更合適(例如,對于文件對象調(diào)用Close就比Dispose更合適),可以通過創(chuàng)建一個private屬性的Dispose方法和public屬性的Close方法,并讓Close調(diào)用Dispose來實現(xiàn)對某些對象調(diào)用Close方法。
    由于不能確定一定會調(diào)用Dispose,而且finalizer的執(zhí)行也是不確定的(我們無法控制GC會在何時運行),C#提供了一個Using語句來保證Dispose方法會在盡可能早的時間被調(diào)用。一般的方法是定義使用哪個對象,然后用括號為這些對象指定一個活動的范圍,當遇到最內(nèi)層的括號時,Dispose方法就會被自動調(diào)用,對該對象進行處理。
    using System.Drawing;
    class Tester
    {
    public static void Main()
    {
    using (Font theFont = new Font("Arial", 10.0f))
    {
    //使用theFont對象
    } // 編譯器將調(diào)用Dispose處理theFont對象
    Font anotherFont = new Font("Courier",12.0f);
    using (anotherFont)
    {
    // 使用anotherFont對象
    } // 編譯器將調(diào)用Dispose處理anotherFont對象
    }
    }
    在本例的第一部分中,F(xiàn)ont對象是在Using語句中創(chuàng)建的。當Using語句結(jié)束時,系統(tǒng)就會調(diào)用Dispose,對Font對象進行處理。在本例的第二部分,F(xiàn)ont對象是在Using語句外部創(chuàng)建的,在決定使用它時,再將它放在Using語句內(nèi),當Using語句結(jié)束時,系統(tǒng)就會調(diào)用Dispose。
    Using語句還能防止其他意外的發(fā)生,保證系統(tǒng)一定會調(diào)用Dispose。