Contents

几种单例模式基类的写法

不继承Mono 线程安全 懒汉模式

namespace ProjectBase.SingleBase
{
    /// <summary>
    /// 单例模式基类 懒汉模式
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Single<T> where T : new()
    {
        public static T Instance = new T();

        protected Single()
        {
        }
    }
}

不继承Mono 线程不安全 饿汉模式

namespace ProjectBase.SingleBase
{
    /// <summary>
    /// 单例模式基类 饿汉模式
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Single<T> where T : new()
    {
        private static T instance;

        public static T Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new T();
                }

                return instance;
            }
        }

        protected Single()
        {
        }
    }
}

不继承Mono 线程安全 饿汉模式

namespace ProjectBase.SingleBase
{
    /// <summary>
    /// 单例模式基类 饿汉模式 线程安全
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Single<T> where T : new()
    {
        public static T Instance => InnerInstance.instance;
        
        protected Single()
        {
        }

        private class InnerInstance //通过静态内部类实现的单例模式
        {
            /// <summary>
            /// 当一个类有静态构造函数时,它的静态成员变量不会被beforefieldinit修饰
            /// 就会确保在被引用的时候才会实例化,而不是程序启动的时候实例化
            /// </summary>
            static InnerInstance()
            {
            }

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

继承Mono

using UnityEngine;
/// <summary>
/// 单例模式基类 继承mono
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingleMono<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance != null) return instance;
            GameObject obj = new GameObject {name = typeof(T).ToString()};
            //让这个单例模式对象在切换场景时不被移除
            DontDestroyOnLoad(obj);
            instance = obj.AddComponent<T>();
            return instance;
        }
    }
}

通过继承单例基类实现的单例模式 虽然可以少写一些代码 但继承是不能私有构造方法的 所以这个单例对象是可以被外界new出来的 目前我没找到解决方法 写代码的时候注意就好了 另外 unity本身是不支持多线程的 基本不需要考虑线程安全的问题 如果是不需要继承mono的单例 第二个是比较好的选择