原理分析:
在C#中,单例模式是一种常见的设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来获取该实例。单例模式的原理是通过私有化构造函数,限制类的实例化操作,同时提供一个静态方法或属性来获取单例实例。
以下是C#中实现单例模式的原理步骤:
1.将类的构造函数私有化:
这样可以防止类被外部代码直接实例化。将构造函数私有化意味着其他类无法使用new关键字来创建该类的实例。
2.创建一个静态私有变量来保存单例实例:
在单例类中定义一个私有的静态变量,用于保存类的唯一实例。
3.创建一个静态的公共方法或属性来访问单例实例:
通过一个公共的静态方法或属性,提供对单例实例的访问。该方法会检查单例实例是否已经存在,如果不存在则创建一个新的实例并返回,如果已存在则直接返回现有实例。
4.确保线程安全性(可选):
在多线程环境下,需要考虑线程安全性。可以使用加锁(lock)或双重检查锁定(double-checked locking)等机制来确保只有一个线程能够创建实例,避免多线程并发访问时创建多个实例。下面是一个使用C#实现单例模式的示例代码:
public class Singleton
{
private static Singleton instance;
private static readonly object lockObject = new object();
private Singleton()
{
// 私有化构造函数
}
public static Singleton GetInstance()
{
if (instance == null)
{
lock (lockObject) // 双重检查锁定机制
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
在上述代码中,通过私有化构造函数Singleton()防止其他类直接实例化Singleton类。使用静态私有变量instance保存Singleton实例。通过静态公共方法GetInstance()来获取Singleton实例,该方法使用双重检查锁定机制以确保线程安全。
使用单例模式的好处是可以节省系统资源,确保类的实例唯一性,并提供一个全局访问点,方便其他类获取该实例。但是需要注意,在某些情况下,滥用单例模式可能导致代码的可测试性和可维护性降低,因此需要谨慎使用。
单例推导过程:
关键字static:将需要全局调用的对象在内存中共享出来
思路:
1.其实需要被共享的一般是属性和方法,
2.其实最终编译出的文件只有一个所以这些属性和方法放到哪里都无所谓,所以可以放到一个文件里统一管理,
3.只要给他合适的机会赋值就ok。
4.unity中赋值可以在start和awake中将值赋值给共享对象即可,也可以通过FindObjectOfType 查找。
游戏开发中的单例介绍:
- 游戏单例:以Unity示例,需要继承MonoBehaviour的需要对引擎做出一些特殊处理的单例生成方式
public abstract class GameInst<T> : MonoBehaviour where T : MonoBehaviour, new() { static T _inst; public static T Inst { get { if (_inst == null) { //错误示范 //_inst = new T(); //正确示范: //_inst= new GameObject().AddComponent<T>();//DonDestroyOnLoad(); //小游戏简写 查找已经存在场景中的类,如果查找不到为null _inst = FindObjectOfType(typeof(T)) as T; } return _inst; } } public static T GetInst() { if (_inst == null) { _inst = FindObjectOfType(typeof(T)) as T; } return _inst; } }
-
数据单例:不需要额外操作,按语言规范新建即可。
public abstract class DataInst<T> where T : new() { static T _inst; public static T Inst { get { if (_inst == null) { _inst = new T(); } return _inst; } } public static T inst { get { if (_inst == null) { _inst = new T(); } return _inst; } } public static T GetInst() { if (_inst == null) { _inst = new T(); } return _inst; } }