zoukankan      html  css  js  c++  java
  • C# 创建单例你会几种方式?

    关于为什么需要创建单例?这里不过多介绍,具体百度知。

      关于C#  创建单例步骤或条件吧

       1、声明静态变量;2、私有构造函数(无法实例化)3、静态创建实例的方法;至于我这里的Singleton是sealed ,只是为了防止被继承,其实有私有构造函数足够了,这里只是为了代码可读性。

      第一种常见的方式创建单例:    

        /// <summary>
        /// 不安全的单例
        /// </summary>
        public sealed class Singleton
        {
            private static Singleton _Singleton;
            private Singleton() { }
            public static Singleton GetSingleton()
            {
                if (_Singleton == null)
                {
                    _Singleton = new Singleton();
                }
                return _Singleton;
            }
        }

    :为什么说是不安全的单例,多线程访问时可能会new多个对象...

      第二种方式创建单例:

       /// <summary>
        /// (多线程)安全单例
        /// </summary>
        public sealed class Singleton
        {
            private static Singleton _Singleton;
            private static readonly object obj = new object();
            private Singleton() { }
            public static Singleton GetSingleton()
            {
                if (_Singleton == null)
                {
                    //加锁保护,在多线程下可以确保实例值被创建一次。缺点是每 次获取单例,都要进行判断,涉及到的锁和解锁比较耗资源。
                    lock (obj)
                    {
                        if (_Singleton == null)
                        {
                            _Singleton = new Singleton();
                        }
                    }
    
                }
                return _Singleton;
            }
        }

    :为了解决上面第一种方式创建的不安全实例问题应用而生。

    第三种方式创建单例:

      /// <summary>
        /// 只读单例
        /// </summary>
        public sealed class Singleton
        {
            private static readonly Singleton instance = new Singleton();
            private Singleton() { }
            public static Singleton Instance
            {
                get
                {
                    return instance;
                }
            }
        }
        /// <summary>
        /// 基于上面的只读单例=自动属性只读单例(语法糖)
        /// </summary>
        public sealed class Singleton
        {
            private Singleton() { }
            public static Singleton Instance { get; } = new Singleton();
        }

    :只读属性式=>借助readonly属性,instance只被初始化一次,同样达到了单例的效果。在引用函数执行第一句话之前,instance其实已经被赋值了,并不是预期的 只有到访问Instance变量时才创建对象。

    第四种方式创建单例

       
        /// <summary>
        /// Singleton中加上静态构造函数。
        /// </summary>
        public sealed class Singleton
        {
            public static readonly Singleton instance = new Singleton();
            private Singleton()
            {
                Console.WriteLine("初始化1!");
            }
            static Singleton()
            {
            }
            public static Singleton Instance
            {
                get { return instance; }
            }
        }

    :为了解决(第三种只读属性实例)在执行第一句代码之前,实例已经被初始化问题。

    第五种方式创建单例:

        /// <summary>
        /// 使用Lazy创建单例,默认是线程安全的
        /// </summary>
        public sealed class Singleton
        {
            private static readonly Lazy<Singleton> instance = new Lazy<Singleton>(() => new Singleton());//
            private Singleton() { }
            public static Singleton Instance
            {
                get
                {
                    return instance.Value;
                }
            }
        }
    // 贴一下关于上面Lazy<T> s=new Lazy<T>()参数的定义;
            // 摘要:
            //    初始化System.Lazy`1类的新实例。 懒惰初始化时
            //    发生时,使用指定的初始化函数和初始化模式。
         
            // 参数:
            //   valueFactory:
            //   被调用以生成延迟初始化值的委托是必需的参数
            //
            //   isThreadSafe:
            //     如果要使此实例可由多个线程同时使用,则为true; false
             //使此实例一次只能由一个线程使用。
            public Lazy(Func<T> valueFactory, bool isThreadSafe);

    作者:课间一起牛

    出处:https://www.cnblogs.com/mhg215/

    声援博主:如果您觉得文章对您有帮助,请点击文章末尾的【关注我】吧!

    别忘记点击文章右下角的【推荐】支持一波。~~~///(^v^)\~~~ .

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

    如果您有其他问题,也欢迎关注我下方的公众号,可以联系我一起交流切磋!

     B站: 课间一起牛的B站         知乎:课间一起牛的知乎

    码云:课间一起牛的码云      github:课间一起牛的github

  • 相关阅读:
    JDOJ 2197: 校门外的树
    简单线段树知识点详解
    求GCD(最大公约数)的两种方式
    USACO Buying Feed, II
    USACO Dueling GPS's
    USACO Milking Cows
    NOIP 2014 比例简化
    USACO Clumsy Cows
    JDOJ 1140: 完数
    NOIP 2008 火柴棒等式
  • 原文地址:https://www.cnblogs.com/mhg215/p/9795478.html
Copyright © 2011-2022 走看看