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();
        }
  • 完成
原文地址:https://www.cnblogs.com/yanlovehan/p/4617872.html