静态类外部不能new,但是内部可以存new出来的对象。
单例模式出自一本书,作者是四个人,外传四仙人设计的一种。
不加readonly可以通过// ? 直接修改静态字段!来破坏Singleton._instance = new Singleton(); // 注意:字段是 private,但可以在类外部修改吗?反转如果不加可以通过反射,各种代码bug来破坏结构。
不会死循环。new Singleton() 在静态初始化时只执行一次,构造函数内部不会再次触发静态字段初始化(CLR 保证类型初始化不可重入)。
静态的就已经写好了,不会出现这种死循环,相反非静态的就可以死循环。
private static readonly Singleton _instance = new Singleton();
// → 堆 0x2000 创建 Singleton 实例
// → 0x1000 里的 _instance 字段赋值为 0x2000
· 0x1000(类型对象)里的 _instance 指向 0x2000(实例)
· 0x2000(实例)里的类型句柄指向 0x1000(类型对象)
当你调用 实例.Test() 时:
1. 先拿到实例,地址 0x2000
2. 通过实例的「类型句柄」找到 0x1000 的类型对象
3. 在 0x1000 的方法表里找到 Test() 方法
4. 执行 Test() 方法
整个过程里不会再次触发 new Singleton(),所以没有死循环。
初始化完以后,0x1000 里的 _instance 就永远是那个 0x2000 的引用,不会再变,也不会再触发 new。
1.我想new类? 被锁死了,创建不来第二个。
2._instance这个调用多次?不好意思只会赋值一次。
3.new Singleton();有没有第二个private static readonly Singleton _instance = new Singleton();之类的?静态只读字段初始化:类第一次被加载到内存时,只执行唯一一次 new;之后无论你调用多少次 Singleton.Instance,只是读取已经存在的 _instance,不会再走 new Singleton();全局内存里永远只有这一个 _instance 对象。
4.Singleton A = Singleton._instance;和Singleton B = Singleton._instance;会不会出现两个示例?不会的,只会有一个,内存地址其实都是一个。
实在反应不过来,就想一个共享的类,只创建了一次也仅仅有一个,在程序开始的时候就帮你实例化过了,你只需要调用即可就行了,而且全局共享使用数据。
https://share.note.youdao.com/ynoteshare/index.html?id=e94e82c43f23962e645d1413d90fd768&type=note&_time=1781667528568
单例模式的核心:一个类只允许创建一个实例,全局共用这一个对象
// 饿汉式 线程安全
public class Singleton
{
// 静态只读实例,程序运行时只创建一次
private static readonly Singleton _instance = new Singleton();
// 私有构造函数:禁止外部 new 创建对象
private Singleton() { }
// 公共访问点,全局获取唯一实例
public static Singleton Instance => _instance;
// 你自己的方法
public void Test()
{
Console.WriteLine("我是饿汉式!");
}
}
//懒汉式(用到时才创建)
//不提前创建实例,第一次使用时才初始化,节省资源
public class LazySingleton
{
// 懒加载,线程安全 Lazy
private static readonly Lazy
new Lazy
private LazySingleton() { }//私有构造 禁止外部 new
public static LazySingleton Instance => _lazyInstance.Value;
public void Test()
{
Console.WriteLine("懒汉式单例");
}
}