Unity中创建单例类基类

来源:互联网 发布:前端js面试题及答案 编辑:程序博客网 时间:2024/06/08 03:59

Unity的开发者一定都对单例熟悉的不能再熟悉了,由于游戏项目功能模块繁多,很多独立的模块都有自己单独的唯一入口,基本上都是用单例实现的,就像:

public class UIManager : MonoBehaviour{private static UIManager _instance;public static UIManager Instance{get{if (_instance == null){_instance = new GameObject(typeof(UIManager).Name).AddComponent<UIManager>();}return _instance;}}}
上面的UIManager就是一个单例类,当第一次访问UIManager.Instance的时候,我们就会在游戏内创建一个名叫“UIManager”的物体,它挂载了我们的单例脚本实例UIManager。

现在有一个问题,假如我有100个单例类要创建,每个类都要复制这段代码很麻烦很不精炼,有没有更清爽的做法?

当然有,我们把单例的实现封装到基类中去就能省去代码复制之苦,可是基类并不知道子类的具体类型,怎么返回子类型的Instance?如果Instance是以基类类型返回的,那么这个基类的存在意义就不大了。但是幸好C#有泛型,我们可以把子类的具体类型以泛型参数T的形式通知给基类,这样基类就能返回子类型。下面是代码:

public class ManagerBase<T> : MonoBehaviour where T : ManagerBase<T>{private static T _instance;public static T Instance{get{if (_instance == null){_instance = new GameObject(typeof(T).Name).AddComponent<T>();}return _instance;}}}
这个基类最重要的代码就是where T : ManagerBase<T>,它限定T必须是ManagerBase<T>的子类,虽然它长的着实有点奇怪。

这时我们再声明单例类UIManager的时候就可以一行代码搞定了:

public class UIManager : ManagerBase<UIManager>{}
这里子类把自己的类型作为泛型参数通知给了基类,基类便知道Instance应该是什么类型了。使用的时候直接访问UIManager.Instance即可。

这个ManagerBase我觉得有点复杂,同时创建了一个私有静态变量_instance和公有静态属性Instance,显得有点冗余,这里我们做个优化:

public class ManagerBase<T> : MonoBehaviour where T : ManagerBase<T>{public static readonly T Instance = new GameObject(typeof(T).Name).AddComponent<T>();}
结束。

0 0
原创粉丝点击