C#的单例模式实现

2021-05-14 14:28

阅读:747

标签:c#   单例模式   

    只能生成一个实例的类是实现了Singleton(单例)模式的类。以下为C#实现单例模式的方式。


    方式一只使用于单线程环境

    // 把构造函数设为私有函数以禁止他人创建实例
    // 定义一个静态的实例在需要的时候创建该实例
    // 在Singlrton的静态属性Instance中只有在instance为null的时候才创建一个实例以避免
    // 重复创建
    // 把构造函数定义为私有函数
    public sealed class Singleton1
    {
        public int a = 2;

        private Singleton1() { }

        private static Singleton1 instance = null;

        public static Singleton1 Instance
        {
            get
            {
                if (instance == null)
                    instance = new Singleton1();
                return instance;
            }
        }
    }
    
 方式二虽然在多线程环境中能工作但效率不高
 
    // 每次通过属性Instance得到Singleton2的实例都会试图加上一个同步锁
    // 而加锁是一个非常耗时的操作在没有必要的时候应该尽量避免
    public sealed class Singleton2
    {
        public int a = 2;
        private Singleton2(){}

        private static readonly object syncObj = new object();

        private static Singleton2 instance = null;

        public static Singleton2 Instance
        {
            get
            {
                lock (syncObj)
                {
                    if (instance == null)
                        instance = new Singleton2();
                }
                return instance;
            }
        }
    }
    
    可行的解法 加同步锁前后两次判断实例是否已存在
    
    // 只有instance为null即没有创建时需要加锁操作。
    public sealed class Singleton3
    {
        private Singleton3() { }

        private static readonly Object syncObj = new Object();

        private static Singleton3 instance = null;

        public static Singleton3 Instance
        {
            get
            {
                if(instance == null)
                {
                    lock(syncObj)
                    {
                        if(instance == null)
                            instance = new Singleton3();
                    }
                }
                return instance;
            }
        }
    }
    
    推荐的解法一利用静态构造函数
    
    // 在初始化静态变量instance的时候创建一个实例
    // 由于C#是在调用静态构造函数时初始化静态变量.NET运行时能够确保只调用一次静态构造
    // 函数保证只初始化一次instance
    public sealed class Singleton4
    {
        private Singleton4() { }

        private static Singleton4 instance = new Singleton4();

        public static Singleton4 Instance
        {
            get
            {
                return instance;
            }
        }
    }
    
    推荐的解法二 实现按需创建实例
    
    // 在内部定义了一个私有类型Nested。
    // 当第一次用到这个嵌套类的时候会调用静态构造函数创建Singleton5的实例instance
    public sealed class Singleton5
    {
        private Singleton5() { }

        public static Singleton5 Instance
        {
            get
            {
                return Nested.instance;
            }
        }

        class Nested
        {
            static Nested() { }

            internal static readonly Singleton5 instance = new Singleton5();
        }
    }
    
    扩展 定义一个表示总统的类型President可以从该类型继承出FrenchPresident
    和AmericanPresident等类型。这些派生类型都只能产生一个实例
    
    public class President
    {
        private string name = "";
        private string country = "";

        public President() { }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public string Country
        {
            get { return country; }
            set { country = value; }
        }
    }
    
    public sealed class FrenchPresident: President
    {
        private FrenchPresident():base() { }

        private static FrenchPresident instance = new FrenchPresident();

        public static FrenchPresident Instance
        {
            get { return (FrenchPresident)(Nested.instance); }
        }

        private class Nested
        {
            static Nested() { }
            internal static readonly FrenchPresident instance = new FrenchPresident();
        }
    }
    
    public sealed class AmericanPresident : President
    {
        private AmericanPresident() : base() { }

        private static AmericanPresident instance = new AmericanPresident();

        public static AmericanPresident Instance
        {
            get { return Nested.instance; }
        }

        private class Nested
        {
            static Nested() { }
            internal static readonly AmericanPresident instance = new AmericanPresident();
        }
    }
    
    实现泛型单例模式
    
    public class SingletonExample where T : class, new()
    {
        public static T Instance
        {
            get { return Nested.instance; }
        }

        private class Nested
        {
            static Nested() { }

            internal static readonly T instance = new T();
        }
    }

    public class Two: SingletonExample
    {
        public int a = 2;

        public void Show()
        {
            Console.WriteLine(a);
        }
    }


本文出自 “许大树” 博客,请务必保留此出处http://abelxu.blog.51cto.com/9909959/1964973

C#的单例模式实现

标签:c#   单例模式   

原文地址:http://abelxu.blog.51cto.com/9909959/1964973


评论


亲,登录后才可以留言!