c# Lazy<T>单例模式 - 延迟初始化单例实例示例与详解
Lazy 延迟初始化单例实例示例与详解
Lazy<T>
是 C# 中用于延迟初始化的类,它允许你在第一次访问对象时才创建实例,而不是在程序启动时就创建实例。这在单例模式中非常有用,因为它可以避免不必要的资源消耗。
1. Lazy 的基本用法
Lazy<T>
的构造函数接受一个委托(Func<T>
),用于定义如何创建实例。
using System;
public class Singleton
{
// 私有构造函数,防止外部实例化
private Singleton() { }
// 定义一个 Lazy<T> 实例
private static readonly Lazy<Singleton> _instance = new Lazy<Singleton>(() => new Singleton());
// 公开的静态属性,用于获取单例实例
public static Singleton Instance => _instance.Value;
}
2. 代码详解
-
Lazy<Singleton>
:- 这里使用
Lazy<Singleton>
来实现延迟初始化。 _instance
是一个静态只读字段,它的类型是Lazy<Singleton>
。
- 这里使用
-
Lazy<T>
的构造函数:new Lazy<Singleton>(() => new Singleton())
:Lazy<T>
的构造函数接受一个委托(Func<T>
),用于指定如何创建实例。- 在这里,我们使用匿名方法
() => new Singleton()
,表示在第一次访问_instance.Value
时才会调用这个方法来创建Singleton
的实例。
-
Instance
属性:public static Singleton Instance => _instance.Value;
:_instance.Value
是Lazy<T>
提供的属性,用于访问实际的Singleton
实例。- 第一次访问
Instance
属性时,Lazy<T>
会调用我们传入的委托来创建实例,并缓存该实例。后续访问时将直接返回缓存的实例。
3. 延迟初始化的好处
-
节省资源:
- 只有在需要时才会创建实例,避免了不必要的资源消耗。
- 例如,在程序启动时不创建所有单例实例,只在实际使用时创建。
-
线程安全:
Lazy<T>
默认是线程安全的。在多线程环境中,_instance.Value
的访问是线程安全的,Lazy<T>
会确保只有一个线程能够创建实例。
-
代码简洁:
- 使用
Lazy<T>
可以简化单例模式的实现,不需要手动编写双重检查锁(Double-Checked Locking)或静态构造函数。
- 使用
4. Lazy 的线程安全性
Lazy<T>
默认是线程安全的。它的实现方式是:
- 在第一次访问
Value
属性时,只有一个线程会执行初始化逻辑(即调用传入的委托)。 - 后续线程访问时,直接返回缓存的实例。
如果不需要线程安全,可以指定 LazyThreadSafetyMode.None
:
private static readonly Lazy<Singleton> _instance = new Lazy<Singleton>(
() => new Singleton(),
System.Threading.LazyThreadSafetyMode.None
);
5. 完整示例:使用 Lazy 实现单例模式
using System;
public class Singleton
{
// 私有构造函数,防止外部实例化
private Singleton()
{
Console.WriteLine("Singleton instance created.");
}
// 定义一个 Lazy<T> 实例
private static readonly Lazy<Singleton> _instance = new Lazy<Singleton>(() => new Singleton());
// 公开的静态属性,用于获取单例实例
public static Singleton Instance => _instance.Value;
// 测试方法
public void DoSomething()
{
Console.WriteLine("Singleton is doing something.");
}
}
class Program
{
static void Main(string[] args)
{
// 第一次访问 Instance 属性时,会创建实例
Singleton.Instance.DoSomething();
// 后续访问直接返回缓存的实例
Singleton.Instance.DoSomething();
}
}
6. 输出结果
运行上述代码,输出如下:
Singleton instance created.
Singleton is doing something.
Singleton is doing something.
可以看到:
- 第一次访问
Instance
时,实例被创建并输出 “Singleton instance created.”。 - 后续访问时,直接返回缓存的实例,不再创建新实例。