c#調試遇到的問題

class Program
    {
        static void Main(string[] args)
        {
            Demo demo1 = new Demo();
        }
    }

public class Demo
    {
        private bool m_Real = false;

        public bool Real
        {
            get { return m_Real; }
            set { m_Real = value; }
        }

        private bool m_Checked = false;

        public bool Checked
        {
            get
            {
                if (!m_Real)
                {
                    m_Real = true;
                    return true;
                }
                return false;
            }
            set { m_Checked = value; }
        }

    }

代碼如上所示,如果在調試時構建demo對象後停止,然後用調試器看對象的變量值得話,那麼就會看到如下效果:


這顯然不是我想要的結果,不過爲什麼會出現這種情況呢?

因爲在查看數據的時候調試器會在取數據的時候把代碼執行一遍然後下邊這段代碼執行了

get
            {
                if (!m_Real)
                {
                    m_Real = true;
                    return true;
                }
                return false;
            }
但是此時你再get裏邊打斷點它是不會停止的,但也確確實實的執行了這塊代碼。


現在把局部變量窗口關掉,再在調試=》窗口裏打開,就會看到如下圖


又會執行一遍獲取所有屬性與字段的代碼。這就說明:即使代碼沒有錯誤,在調試的時候我所看到的也不一定是我想要的,調試器會執行一段代碼,並且不會被斷點打住。

(鼠標指上去,局部變量,監視裏的打開時都會使調試器執行一遍代碼)

那麼如果把代碼改成如下會怎麼樣呢?

public class Demo
    {
        

        private bool m_Checked = false;

        public bool Checked
        {
            get
            {
                if (!m_Real)
                {
                    m_Real = true;
                    return true;
                }
                return false;
            }
            set { m_Checked = value; }
        }

        private bool m_Real = false;

        public bool Real
        {
            get { return m_Real; }
            set { m_Real = value; }
        }
        
    }


結果是還是一樣的,沒有任何變化;這說明調試器去取變量值得時候並不是按順序的,

那麼應該如何解決這個問題呢?我目前的想法如下:

首先:這個代碼設計的本身就不合理,在調試時看到的m_Checked和Checked在第一次看的時候不匹配,所以不應該在Checked屬性中返回特定的值,無論如何都應該對m_Checked進行返回。

其次:調試器只會在調試查看的時候獲取一下屬性和字段的值,並不會把方法也執行一遍。


所以代碼如下:

public class Demo
    {
        private bool m_Real = false;

        public bool Real
        {
            get { return m_Real; }
            set { m_Real = value; }
        }

        private bool m_Checked = false;

        public bool Checked
        {
            get { return m_Checked; }
            set { m_Checked = value; }
        }

        public bool GetChecked()
        {
            if (!m_Checked)
            {
                m_Real = true;
            }
            return Checked;
        }
    }
使用GetChecked()方法在調試器查看的時候並不會執行,所以也就不會改變m_Real的值,只有在真正代碼裏(自己想好的位置)獲取值得時候纔會調用GetChecked改變m_Real的值(注意:這個GetChecked()方法也不能放在屬性的Get方法裏)。這裏既然使用了GetChecked就不要再使用Checked的屬性,應該把其注掉,除非你有特殊的用途,否則在一定的情況下會把自己搞迷糊。PS:可以從這理解理解爲什麼有的類提供Property和GetProperty()


綜上所述:不要在屬性的Get裏邊(裏邊調用方法則接着往裏找)對另一個屬性或字段進行修改賦值,以免引起不必要的調試麻煩,如果想在取一個屬性值得時候改變另一個屬性或字段的值,請用方法來做,不要直接在屬性的Get裏邊操作。


以上所述的對於直接執行不會有任何影響,只會影響調試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章