建立類別 與 解構
先建立類別 利用~來解構類別 並SHOW出訊息告知已解構
class Father 
        {
            public Father()
            {
                MessageBox.Show("類別狀態:建構 Father");
            }
            ~Father() 
            {
                MessageBox.Show("類別狀態:解構 Father");
            }
        }
        
        class Son : Father 
        { 
            public Son()
            {
                MessageBox.Show("類別狀態:建構 Son"); 
            } 
            ~Son() 
            {
                MessageBox.Show("類別狀態:解構 Son"); 
            } 
        }
再來 來試試看 執行的步驟 建立BUTTON
private void button1_Click(object sender, EventArgs e)
        {
            richTextBox1.Text = "程式開始" + "\n"; ;
            Son me = new Son(); 
            me = null;
            richTextBox1.Text += "程式結束" + "\n";
            //直到程式被關閉 才會執行解構
        }
執行 先後順序 如下
程式開始
建構FATER
建構SON
程式結束
會發現程式 尚未解構
直到把程式關閉 才SHOW出 解構訊息
因為使用~來解構 會呼叫Object.Finalize方法
而Finalize只是 允許物件在記憶體回收進行回收之前,嘗試釋放資源並執行其他清除作業。
下面列子中 與上一樣 不同與加入 GC強迫回收!
PS:使用 同上一樣的類別
private void button2_Click(object sender, EventArgs e)
        {
            richTextBox1.Text = "程式開始" + "\n";
            Son me = new Son(); 
            me = null;
            richTextBox1.Text += "開始執行強迫回收"+"\n";
            //以GC指令強迫.Net framework資源回收
            GC.Collect();
            //並使用WaitForPendingFinalizers method等到確實回收後
            //再繼續執行,因為資源回收時是在另一個thread之故。
            GC.WaitForPendingFinalizers();
            richTextBox1.Text += "程式結束" + "\n";
        }執行順序為
程式開始
建構FATER
建構SON
解構SON
解構FATER
程式結束
可以程式尚未結束 先進行回收
再來可以使用IDisposable介面
類別程式碼如下
class FFather : IDisposable //父類別直接指向IDisposable
        { 
            public FFather() 
            {
                MessageBox.Show("類別狀態:建構 FFather");
            } 
            public void Dispose() 
            {
                MessageBox.Show("類別狀態:解構 FFather"); 
            } 
        }
        class SSon : FFather, IDisposable 
        { 
            public SSon() 
            { 
                MessageBox.Show("類別狀態建構 SSon"); 
            } 
            new public void Dispose() 
            { 
                MessageBox.Show("類別狀態解構 SSon"); 
            } 
        }一樣寫個BUTTON來看執行順序
private void button3_Click(object sender, EventArgs e)
        {
            richTextBox1.Text = ("程式開始"); 
            using (SSon me = new SSon()) 
            {
                richTextBox1.Text += ("程式執行中"); 
            }
            richTextBox1.Text += ("程式結束");
            //只有呼叫子類別的回收
        }
執行順序如下
程式開始
建構FFATHER
建構SSON
解構SSON
程式結束
PS:一定會覺得奇怪 FFATHER怎沒被解構?
Net framework只呼叫子類別的Dispose method 卻沒有呼叫父類別的Dispose method,所以,實作IDisposable介面時,父類別的資源回收要由子類別呼叫
請看下面 類別改寫 加入base.Dispose()
class FFFather : IDisposable //父類別直接指向IDisposable
        {
            public FFFather()
            {
                MessageBox.Show("類別狀態:建構 FFFather");
            }
            public void Dispose()
            {
                MessageBox.Show("類別狀態:解構 FFFather");
            }
        }
        class SSSon : FFFather, IDisposable
        {
            public SSSon()
            {
                MessageBox.Show("類別狀態建構 SSSon");
            }
            new public void Dispose()
            {
                MessageBox.Show("類別狀態解構 SSSon");
                base.Dispose();
            }
        }
執行順序如下
程式開始
建構FFFATHER
建構SSSON
解構SSSON
解構FFFATHER
程式結束
注意使用 IDisposable介面時候
建立物件時 務必使用 using
如果不使用using IDisposable將毫無作用
 
沒有留言:
張貼留言