Unity中创建单例类基类

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>();
}
结束。

猜你喜欢

转载自blog.csdn.net/lzdidiv/article/details/70158006