c#及unity单例模板

c#:使用泛型实现单例

using System; 
using System.Collections.Generic; 
using System.Text; using System.Reflection;
 /// <summary> /// 1.泛型 /// 2.反射 /// 3.抽象类 /// 4.命名空间 /// </summary>
 namespace QFramework 
{
  public abstract class QSingleton<T> where T : QSingleton<T> 
  {
    protected static T instance = null; protected QSingleton() { } 
      public static T Instance() 
      {
      if (instance == null) 
      {
             // 先获取所有非public的构造方法
             ConstructorInfo[] ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); 
            // 从ctors中获取无参的构造方法 
            ConstructorInfo ctor = Array.Find(ctors, c => c.GetParameters().Length == 0);
             if (ctor == null)
                 throw new Exception("Non-public ctor() not found!"); 
            // 调用构造方法
             instance = ctor.Invoke(null) as T; 
      } 
    return instance; 
    } 
  } 
}

unity实现MonoBehaviour 单例,约束GameObject的个数,这个需求,还没有思路,只好在游戏运行时判断有多少个GameObject已经挂上了该脚本,然后如果个数大于1抛出错误即可。在脚本销毁时,把静态实例置空。 

using UnityEngine;
 /// <summary> /// 需要使用Unity生命周期的单例模式 /// </summary> 
namespace QFramework
{ 
  public abstract class QMonoSingleton<T> : MonoBehaviour where T : QMonoSingleton<T> 
  { 
      protected static T instance = null;
    public static T Instance() 
    { 
          if (instance == null) 
          { 
             instance = FindObjectOfType<T>();
        if (FindObjectsOfType<T>().Length > 1)
             { 
                QPrint.FrameworkError ("More than 1!"); 
                return instance; 
        }
             if (instance == null) 
        {
                 string instanceName = typeof(T).Name; QPrint.FrameworkLog ("Instance Name: " + instanceName); 
                GameObject instanceGO = GameObject.Find(instanceName);
                if (instanceGO == null) instanceGO = new GameObject(instanceName); 
                instance = instanceGO.AddComponent<T>(); 
                DontDestroyOnLoad(instanceGO);
                 //保证实例不会被释放 
                QPrint.FrameworkLog ("Add New Singleton " + instance.name + " in Game!"); 
            }
             else {
                 QPrint.FrameworkLog ("Already exist: " + instance.name); 
            }
         } 
        return instance; 
    }
   protected virtual void OnDestroy() 
  { instance
= null;   } }

 

转载于:https://www.cnblogs.com/wang-jin-fu/p/8313311.html

### Unity 中实现模式的最佳实践 在 Unity 中,为了确保某些常用脚本在整个游戏运行期间只存在一个实,并且便于其他组件访问该实,通常会采用模式。这种设计模式能够简化对象之间的交互逻辑。 #### 模式的基本结构 对于大多数情况而言,在 C# 编写的 MonoBehaviour 组件内创建静态属性 `Instance` 来保存自身的唯一引用是一个常见的做法[^5]: ```csharp public class MySingleton : MonoBehaviour { private static MySingleton instance; public static MySingleton Instance { get { if (instance == null) { instance = FindObjectOfType<MySingleton>(); if (instance == null) { GameObject singletonObject = new GameObject(); instance = singletonObject.AddComponent<MySingleton>(); singletonObject.name = typeof(MySingleton).ToString() + " (Singleton)"; } } return instance; } } } ``` 这段代码展示了如何通过查找现有对象或新建的方式获取。 #### 确保线程安全性 当涉及到多线程环境时,为了避免竞争条件的发生,应当考虑加入同步机制来保护 `_instance` 的初始化过程。一种有效的方法是在首次检测到为空的情况下使用锁定语句(`lock`)来进行二次验证并完成实化工作][^[^23]: ```csharp using System; public abstract class ThreadSafeSingleton<T> where T : class, new() { private static volatile T _instance; private static readonly object Locker = new object(); public static T Instance { get { if (_instance == null) { lock (Locker) { if (_instance == null) _instance = new T(); } } return _instance; } } } ``` 此版本利用了双重检查锁定技术以及 `volatile` 关键字以防止指令重排序带来的潜在问题[^3]。 #### 泛型模板 为了让模式更加通用灵活,可以将其定义为泛型类的形式,从而允许任何继承自特定基类型的子类都能轻松地成为: ```csharp public abstract class GenericSingleton<T> where T : Component { protected GenericSingleton() {} private static T _instance; public static T Instance { get { if (_instance != null) return _instance; _instance = FindObjectOfType<T>(); if (_instance != null) return _instance; var singletonObj = new GameObject(typeof(T).Name); _instance = singletonObj.AddComponent<T>(); DontDestroyOnLoad(singletonObj); return _instance; } } } ``` 上述代码片段提供了一个适用于所有 MonoBehaviours 子类的基础框架,同时也包含了持久化的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值