一、C#下的单例模式
C#实现单例模式首先要看C# in Depth的一章Implementing the Singleton Pattern in C#
下面是链接:
http://csharpindepth.com/Articles/General/Singleton.aspx
介绍了Lazy和不Lazy的区别,线程安全。
下面是一个中文的更详细的解释说明
http://www.cnblogs.com/rush/archive/2011/10/30/2229565.html
其他文章基本上就是这些东西翻来覆去的讲,没有更多新意了,包括MSDN的文章。
二、怎么样不重复写代码
1)使用泛型
单例作为一个构造模式,实际上有两个要求
a)不能通过new关键字进行构造,只能通过GetInstance()获取实例。 (构造函数加private)
b)不能继承 (类加sealed)
而如果使用泛型,并且通过new关键字构造这个类,那这个类就必须要有一个公共的构造函数。这和单例模式是矛盾的。
一定要处理这个问题的话一个办法是使用反射。
但同样,如果能使用反射获得这个类的实例,那么整个单例模式都没什么意义,任何人总能获取到这个类的实例,所以还是不要自欺欺人了,就把构造函数公开出来算了。
https://www.codeproject.com/tips/696330/thinking-in-singleton-instead-of-a-useful-generic
一个使用反射实现的单例
2)使用Code Snippet功能
这确实也是一个解决方案,就看你是否可以忍受大量看起来重复的代码了。
https://stackoverflow.com/questions/380755/a-generic-singleton
三、Unity3D下的单例模式
Component创建实例的方法多了AddComponent(泛型或者非泛型版本)。
当然还有一些其他的可能,比如加载Prefab,加载场景等等。
要保证Component的唯一,一般在Start或者Awake的时候检查instance,并且将多余的实例销毁掉。
当然,我并不觉得有什么必要,甚至觉得不应该将Component作为单例。
代码可以参考:
http://wiki.unity3d.com/index.php/Singleton
https://unity3d.com/cn/learn/tutorials/projects/2d-roguelike-tutorial/writing-game-manager
四、单例模式的讨论
Game Programming Patterns - Singleton
http://gameprogrammingpatterns.com/singleton.html
http://gpp.tkchu.me/singleton.html (翻译版)
附:一个例子
public class Singleton<T> where T : class, new() { protected Singleton() { } public static T Instance { get { return SingletonCreator.Instance; } } private static class SingletonCreator { static SingletonCreator() { } // ReSharper disable once StaticFieldInGenericType // ReSharper disable once MemberHidesStaticFromOuterClass internal static readonly T Instance = new T(); } }
代码来自于:Implementing the Singleton Pattern in C# - Fifth version - fully lazy instantiation
目前的Unity(5.6)并不支持Lazy。
用法1:
Singleton<C>.Instance.Method();
用法2:
class C : Singleton<C>
{
//......
}
C.Instance.Method();