6. 单例基类-C#

对于普通C#脚本类,不必挂载在游戏场景内的物体上,也就不会出现在Inspector面板上,不继承MonoBehavior类。

单例模式

整个游戏内全局只持有一份实例。

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

使用泛型T来指定实例类型,同时使用无参构造函数约束new和基类约束,new确保在类内可以对T进行实例化,基类约束的意义是限定传进来的泛型参数为SingleTon的子类,写的时候把自己传进去,套娃。
由于全局唯一,故使用静态属性Instance并在获取属性时判断属性是否为空,为空new一个,不为空直接返回。

使用时需要运用单例模式的C#类直接继承SingleTion即可,示例如下。

6. 单例基类-C#_第1张图片

构造函数私有化,外部不能new,不写这个构造函数则会默认有一个公有的构造函数,外部就可以new,这样不符合单例模式,我们希望new发生在第一次调用属性Get对象时自动执行。

加断点调试可以发现,第一次进入SingleTon时instance为空,会先去new一次对象。

这里需要额外说明的是:
以上通过属性实现在get时才真正实例化对象的Lazy Loading模式避免了资源浪费,被称作为懒汉式单例。但懒汉式也存在线程不安全的问题,当多个线程进入if(instance == null)逻辑时,对象的创建就可能会产生多个实例,Unity中由于一般不采用多线程的开发方式,所以懒汉式一般可满足要求,如果有必要可以使用双重校验的懒汉式单例,可参考。

与懒汉式相对的另一种单例模式是饿汉式,其会在类加载时就new好对象,线程安全。缺点就是有可能会造成资源浪费,在我没用到这个单例的时候就对单例进行了实例化,如果以后一直不用会产生内存浪费。

    public abstract class Singleton<T> where T : Singleton<T>, new()
    {
        private static T instance = new T();
		private T(){}
        public static T Instance
        {
            get
            {
                return instance;
            }
        }
    }

你可能感兴趣的:(Unity,c#,单例模式,java)