c#單例模式的簡單介紹


  • 單例模式的引入
    • 在講解什么是單例模式之前,我們先引入這樣一個問題,在Winform開發的過程中,實現點擊一個按鈕彈出一個窗體,那么怎樣控制點擊按鈕后彈出額窗體只有一個,如果窗體已經彈出,就不再彈出新的窗體。解決方案有如下三種(先做簡單的介紹,之后逐一進行詳細講解)
      • 方案一:使用ShowDialog()方法彈出,這種方法也是最簡單粗暴屌到家的方法
      • 方案二:使用邏輯語句判斷當前窗體是否已經打開,如果打開,就不知執行再次打開操作
      • 方案三:使用單例模式(引入單例模式)
  • 示例工程建立講解
    • 建立一個Winform工程
    • Form1為主窗體,添加Form2窗體為被彈出窗體,在窗體上放置兩個按鈕,button1和button2,這兩個按鈕被點擊的時候都彈出Form2
  • 詳解方案一:
    • 這種方法簡單實現不能,只要在這兩個按鈕的click事件中添加如下代碼就可以實現,但點擊后,如果Form2窗體不關閉的話,Form1主窗體無法繼續操作,詳情請查閱ShowDialog()方法的使用
        private void button1_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();
            f2.ShowDialog();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();
            f2.ShowDialog();
        }
  •  詳解方案二:
    • 直接上代碼
        Form2 f2 = null;
        private void button1_Click(object sender, EventArgs e)
        {
            if (f2 == null||f2.IsDisposed)
            {
                f2 = new Form2();
                f2.Show();
            }
            else
            {
                f2.Show();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (f2 == null || f2.IsDisposed)
            {
                f2 = new Form2();
                f2.Show();
            }
            else
            {
                f2.Show();
            }
        }

 

    • 代碼簡單不解釋,這里重點說一下IsDisposed屬性的使用,如果判斷該屬性的話,當點擊一次按鈕,關閉Form2窗體,再次點擊的時候會報錯,請自己嘗試,因為當關閉窗體的時候,f2變量並沒有重置為null,但是窗體已經被釋放了,所以需要判斷一下;IsDisposed:獲取一個值,該值指示控件是否已經被釋放;如果控件已經被釋放,則為 true;否則為 false。
  • 詳解方案三:
    • 這種方法也是這次的重點就是使用了單例模式進行編碼,所謂優缺點自行找資料分析,學習只是就是想要使用不同的手段實現相同的功能,這樣才能解放自己的思維和思考方式
    • 在講解這種之前,我們先講解一下什么是單例模式?怎么事項單例模式?單例模式通俗的來講就是控制一個類只能new一個對象
    • 直接上代碼,單例模式類的示例代碼
    /// <summary>
    /// 這個類只能new一個對象
    /// </summary>
    public class Singleton
    {
        private static Singleton _instance;

        private static readonly object syn = new object();

        /// <summary>
        /// 把類的構造函數訪問權限設置為private,則該類不能在外界被new了
        /// </summary>
        private Singleton() { }

        /// <summary>
        /// 在當前類型中創建一個靜態的方法,用該靜態方法來返回一個對象
        /// </summary>
        /// <returns></returns>
        public static Singleton CreateInstance()
        {
            if (_instance == null)
            {
                lock (syn)
                {
                    if (_instance == null)
                    {
                        _instance = new Singleton();
                    }
                }
            }
            return _instance;
        }
    }

 

    • 以上代碼,使用線程鎖解決了多線程訪問的時候發生的問題
    • 使用如下代碼進行調用判斷
        static void Main(string[] args)
        {
            Singleton s1 = Singleton.CreateInstance();
            Singleton s2 = Singleton.CreateInstance();
            //確定指定的 System.Object 實例是否是相同的實例。
            Console.WriteLine(object.ReferenceEquals(s1, s2));
            Console.ReadKey();
        }

 

    • 返回的結果為Ture
    • 那么以上就是單例模式的簡單示例,接下來我們來解決一下之前窗體彈出的問題
    • Form2窗體代碼
    public partial class Form2 : Form
    {
        private Form2()
        {
            InitializeComponent();
        }

        private static Form2 _f2;

        public static Form2 CreateForm()
        {
            if (_f2 == null || _f2.IsDisposed)
            {
                _f2 = new Form2();
            }
            return _f2;
        }
    }

 

    • 調用代碼
        private void button1_Click(object sender, EventArgs e)
        {
            Form2 f2 = Form2.CreateForm();
            f2.Show();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Form2 f2 = Form2.CreateForm();
            f2.Show();
        }

 

  • 完成


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM