c#泛型与单例

c#泛型与单例

你好! 这是 泛型与单例 所展示的欢迎页。

单例类

普通单例类:

	/// <summary>
    /// 单例模式的实现
    /// </summary>
    public class Singleton
    {
    
    
        // 定义一个静态变量来保存类的实例
        private static Singleton uniqueInstance;

        // 定义一个标识确保线程同步
        private static readonly object locker = new object();

        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
    
    
        }

        /// <summary>
        /// 定义公有方法提供一个全局访问点,
        /// 同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static Singleton GetInstance()
        {
    
    
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,
            /// 首先检测到locker对象为"加锁"状态,
            /// 该线程就会挂起等待第一个线程解锁
            /// lock语句运行完之后(即线程运行完之后)
            /// 会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (uniqueInstance == null)
            {
    
    
                lock (locker)
                {
    
    
                    // 如果类的实例不存在则创建,否则直接返回
                    if (uniqueInstance == null)
                    {
    
    
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }
    }

单例泛型类-作为基类

特点1:where 约束:引用类型/值类型

where T:class 是 引用类型约束,使用class关键字
引用类型约束将一个类型形参限定为引用类型。
引用类型一般是用户定义的类型,包含类/接口/委托/字符串和数组类型。
在这个where子句中,class关键字是指定T必须是引用类型。因此,尝试对T使用值类型,将会导致编译错误。

where T:struct 是 值类型约束,使用struct关键字
值类型约束将一个类型形参限定为值类型。
值类型派生于System.ValueType类型。基元和结构都是值类型。
在该形式中,struct关键字指定T必须是值类型。因此,尝试对T使用引用类型,将导致编译错误。

特点2:where 约束:new()【new不支持私有的无参构造函数】

使用new()约束时应当注意:
1.new()约束可以与其他约束一起使用,但必须位于约束列表的末端
2.new()约束仅允许开发人员使用无参数的构造函数构造一个对象,
即使同时存在其他的构造函数也是如此。即不允许给类型形参的构造
函数传递实参。
3.不可以同时使用new()约束和值类型约束。因为值类型都隐式的提
供了一个无参公共构造函数。
就如同定义接口时指定访问类型为public一样,编译器会报错,因为接口一定是public的。

特点3:双重线程锁,更加安全

class Singleton<T> where T: class,new()  
{
    
      
    private static T _instance;  
    private static readonly object syslock=new object();  
  
    public static T getInstance()   
    {
    
      
        if (_instance == null)  
        {
    
      
            lock (syslock) {
    
      
                if (_instance == null)  
                {
    
      
                //T如果没有约束new() 这里是不允许new的
                    _instance = new T();  
                }  
            }  
        }  
       return _instance;  
    }  
} 

以下代码是 不支持私有的无参构造函数的单例泛型

public abstract class BaseInstance<T> where T : class,new()
    {
    
    
        private readonly static object lockObj = new object();
        private static T instance = null;
        public static T Instance
        {
    
    
            get
            {
    
    
                if (instance == null)
                {
    
    
                    lock (lockObj)
                    {
    
    
                        if (instance == null)
                        {
    
    
                            instance = new T();
                        }
                    }
                }
                return instance;
            }
        }
    }

以下代码是 支持私有的无参构造函数的单例泛型

public class BaseInstance<T> where T : class//new(),new不支持非公共的无参构造函数 
    {
    
    
        /*
         * 单线程测试通过!
         * 多线程测试通过!
         * 根据需要在调用的时候才实例化单例类!
          */
        private static T _instance;
        private static readonly object SyncObject = new object();
        public static T Instance
        {
    
    
            get
            {
    
    
                if (_instance == null)//没有第一重 singleton == null 的话,每一次有线程进入 GetInstance()时,均会执行锁定操作来实现线程同步,
                //非常耗费性能 增加第一重singleton ==null 成立时的情况下执行一次锁定以实现线程同步
                {
    
    
                    lock (SyncObject)
                    {
    
    
                        if (_instance == null)//Double-Check Locking 双重检查锁定
                        {
    
    
                            //_instance = new T();
                            //需要非公共的无参构造函数,
                            //不能使用new T() ,new不支持非公共的无参构造函数 
                            _instance = (T)Activator.CreateInstance(typeof(T), true); 
                            //第二个参数防止异常:“没有为该对象定义无参数的构造函数。”
                        }
                    }
                }
                return _instance;
            }
        }
        public static void SetInstance(T value)
        {
    
    
            _instance = value;
        }
    }

单例泛型的使用-继承

作为面向对象的三大特性:封装、继承、多态 (抽象,严格来说不算)。
继承之后,可以调用父类的方法【GetInstance()】,获取到本类(子类)的实例【new()之后的对象】,全局单独存在,独一无二。
这个实例可以调用本类的所有方法和属性进行操作。

class myclass : Singleton<myclass> {
    
      
    public void ss() {
    
      
        Console.WriteLine("111");  
    }  
}  
///在main或者指定函数调用如下:
myclass.getInstance().ss();  

泛型单例使用方法2-封装

调用类的静态方法 ,直接返回该类型的实例:

public class NetIO 
{
    
    

    public static NetIO GetInstance()
    {
    
    
        return SingletonProvider<NetIO>.Instance;
    }

    public NetIO()
    {
    
    
        this.NetIoCreateTime = DateTime.Now;
    }

    public DateTime NetIoCreateTime
    {
    
    
        get {
    
     return _ct; }
        set {
    
     _ct = value; }
    }

    private DateTime _ct;
}

C#在Unity中的单例

using System;
using UnityEngine;

public class SingletonProvider<T> where T : class ,new()
{
    
    
    private SingletonProvider()
    {
    
    
    }

    private static T _instance;
    // 用于lock块的对象
    private static readonly object _synclock = new object();

    public static T Instance
    {
    
    
        get
        {
    
    
            if (_instance == null)
            {
    
    
                lock (_synclock)
                {
    
    
                    if (_instance == null)
                    {
    
    
                        // 若T class具有私有构造函数,那么则无法使用SingletonProvider<T>来实例化new T();
                        _instance = new T();
                        //测试用,如果T类型创建了实例,则输出它的类型名称
                        Debug.Log("{0}:创建了单例对象" + typeof(T).Name);
                    }
                }
            }
            return _instance;
        }
        set {
    
     _instance = value; }
    }
}

下边还没想好。。。

猜你喜欢

转载自blog.csdn.net/weixin_38531633/article/details/108975868