Unity3d中 C# 单例类 <泛型>
2013-01-16 17:06
141 查看
此篇文章是以Unity3d 中 使用C#为语言为前提的.
1. 在C#中使用泛型单利的话, 我们可以非常简单的用好几种不同方式去实现. 比如写一个我经常写的手法:
public class BO<T> where T : new(){
private static T _It;
public static T It {
get{
if (_It == null){
_It = new T();
}
return _It;
}
}
}
在使用过程中,只要把class的父类继承自 BO<T> , 这样类就会多出一个静态成员变量It. 通过It成员可以访问全局唯一一个单例. (这里没有加入锁之类的,只是简单描述单例思想!)
思考: Unity3d 可以用C#来实现, 那么上面的单例类可以用到我们的项目中吗?如果不行,为什么呢?
在此就不写验证和思考过程了, 我直接给出答案和解决方法, 如果大家有时间可以去验证下.
答案:
1. Unity3d中, 如果不切换场景, 简单的说,如果程序启动到结束都不(Application.LoadLevel() || Application.LoadLevelAsync()) 转换场景, 那么上面的类一点问题都没有.
2. 在我们在一个场景中使用的好好的一个单例类(私有成员,其他各种成员都保存着值),如果我们切换了场景后, 我们会神奇的发现, 我们单例类的_It 变成了NULL, 也就是说切换过程中,把 BO<T>._It 这个私有成员释放了,变成NULL, 这下可不好了,单例,故名思议就是要整个程序运行期间只有一个实例,且成员值和引用不会被系统丢弃!
3. Unity3d在Object类中提供了一个静态函数 :Object.DontDestroyOnLoad (Object target) . 加载新场景的时候使目标物体不被自动销毁. yes,这货就是我们想要的.
4. 那么只要在我们的上面类添加一个脚本,基本就可以实现功能咯. 下面贴我们在项目中使用的单例类.
文件:
GameNotDestory.cs
public class GameNotDestory : MonoBehaviour {
void Awake (){
DontDestroyOnLoad( this );
}
}
VO.cs
class _VO : MonoBehaviour{
private static _VO _it;
public static _VO It {
get {
return _it;
}
}
static _VO (){
GameObject _voObject = new GameObject("VO Parent(NoDestory)");
_it = _voObject.AddComponent<_VO> ();
_voObject.AddComponent<GameNotDestory> ();
}
}
public class VO<T> : MonoBehaviour
where T : VO<T> {
private static T _Instance;
public static T It {
get{
if (_Instance == null){
_Instance = (T)GameObject.FindObjectOfType(typeof(T));
if (_Instance == null){
GameObject instanceObject = new GameObject(typeof(T).Name);
_Instance = instanceObject.AddComponent<T>();
instanceObject.AddComponent<GameNotDestory> ();
instanceObject.transform.parent = _VO.It.transform;
}
else{
GameNotDestory dotDestory = _Instance.gameObject.GetComponent<GameNotDestory> ();
if (dotDestory == null){
_Instance.gameObject.AddComponent<GameNotDestory> ();
}
}
}
return _Instance;
}
}
}
搞定~~. 使用中,只要把类继承自VO<T>, 在Unity3d中就会保持单例,哈哈~
1. 在C#中使用泛型单利的话, 我们可以非常简单的用好几种不同方式去实现. 比如写一个我经常写的手法:
public class BO<T> where T : new(){
private static T _It;
public static T It {
get{
if (_It == null){
_It = new T();
}
return _It;
}
}
}
在使用过程中,只要把class的父类继承自 BO<T> , 这样类就会多出一个静态成员变量It. 通过It成员可以访问全局唯一一个单例. (这里没有加入锁之类的,只是简单描述单例思想!)
思考: Unity3d 可以用C#来实现, 那么上面的单例类可以用到我们的项目中吗?如果不行,为什么呢?
在此就不写验证和思考过程了, 我直接给出答案和解决方法, 如果大家有时间可以去验证下.
答案:
1. Unity3d中, 如果不切换场景, 简单的说,如果程序启动到结束都不(Application.LoadLevel() || Application.LoadLevelAsync()) 转换场景, 那么上面的类一点问题都没有.
2. 在我们在一个场景中使用的好好的一个单例类(私有成员,其他各种成员都保存着值),如果我们切换了场景后, 我们会神奇的发现, 我们单例类的_It 变成了NULL, 也就是说切换过程中,把 BO<T>._It 这个私有成员释放了,变成NULL, 这下可不好了,单例,故名思议就是要整个程序运行期间只有一个实例,且成员值和引用不会被系统丢弃!
3. Unity3d在Object类中提供了一个静态函数 :Object.DontDestroyOnLoad (Object target) . 加载新场景的时候使目标物体不被自动销毁. yes,这货就是我们想要的.
4. 那么只要在我们的上面类添加一个脚本,基本就可以实现功能咯. 下面贴我们在项目中使用的单例类.
文件:
GameNotDestory.cs
public class GameNotDestory : MonoBehaviour {
void Awake (){
DontDestroyOnLoad( this );
}
}
VO.cs
class _VO : MonoBehaviour{
private static _VO _it;
public static _VO It {
get {
return _it;
}
}
static _VO (){
GameObject _voObject = new GameObject("VO Parent(NoDestory)");
_it = _voObject.AddComponent<_VO> ();
_voObject.AddComponent<GameNotDestory> ();
}
}
public class VO<T> : MonoBehaviour
where T : VO<T> {
private static T _Instance;
public static T It {
get{
if (_Instance == null){
_Instance = (T)GameObject.FindObjectOfType(typeof(T));
if (_Instance == null){
GameObject instanceObject = new GameObject(typeof(T).Name);
_Instance = instanceObject.AddComponent<T>();
instanceObject.AddComponent<GameNotDestory> ();
instanceObject.transform.parent = _VO.It.transform;
}
else{
GameNotDestory dotDestory = _Instance.gameObject.GetComponent<GameNotDestory> ();
if (dotDestory == null){
_Instance.gameObject.AddComponent<GameNotDestory> ();
}
}
}
return _Instance;
}
}
}
搞定~~. 使用中,只要把类继承自VO<T>, 在Unity3d中就会保持单例,哈哈~
相关文章推荐
- [C#]泛型与非泛型集合类的区别及使用例程,包括ArrayList,Hashtable,List<T>,Dictionary<Tkey,Tvalue>,SortedList<Tkey,Tvalue>,
- 【C#基础知识】——List<T>And Dictionary<K,V>泛型集合
- c# 图解泛型List<T>, HashTable和Dictionary<TKey,TValue>
- C#中string[]数组和list<string>泛型的相互转换
- [C#基础知识]泛型Dictionary<string,string>的用法详解
- C#泛型集合List<T>自带方法之排序
- C# List<T>用法 泛型 (转)
- C#ArrayList 集合 和list<t>泛型集合
- C# 泛型约束List<T> (转)
- [C#] 泛型委派 Action<T> 與 Func<T>
- C# List<T> 泛型的反射, 泛型 函数的反射
- C#编程:泛型中接口IEnumerable<T>中GetEnmerator方法的讨论
- [C#]泛型与非泛型集合类的区别及使用例程,包括ArrayList,Hashtable,List<T>,Dictionary<Tkey,Tvalue>,SortedList<Tkey,Tvalue>,Queue<T>,Stack<T>等
- C#中string[]数组和list<string>泛型的相互转换
- C# 泛型List<T>学习总结
- C# 泛型约束 xxx<T> Where T:约束(一)
- C#中数组[],ArrayList,List<T>泛型的区别
- 读<<CLR via C#>>总结(13) 详谈泛型
- c# 泛型集合Dictionary<TKey,TValue>
- C#中string[]数组和list<string>泛型的相互转换 【转】