C# Lazy的用法 – 实现延迟初始化

15次阅读

Lazy是C#中实现延迟初始化的泛型类,仅在首次访问Value属性时创建实例,支持线程安全模式控制,适用于高开销或非必需对象的按需加载。

C# Lazy的用法 – 实现延迟初始化

Lazy 是 C# 中用于实现延迟初始化(lazy initialization)的泛型类。它的核心作用是:在真正需要使用对象时才创建实例,而不是在声明时就立即初始化。这种方式可以提升性能,尤其适用于创建开销大或可能根本不会被使用的对象。

基本用法

使用 Lazy 很简单,只需将类型 T 作为泛型参数,并传入一个委托来定义如何创建对象。

Lazy lazyObject = new Lazy(() => new ExpensiveObject()); 

// 此时并未创建实例 // ...

// 第一次访问 Value 时才会创建 ExpensiveObject obj = lazyObject.Value; // 实例化发生在这里

只有第一次调用 Value 属性时,内部的工厂函数才会执行,之后的所有访问都会返回同一个缓存实例。

线程安全控制

Lazy 默认是线程安全的,多个线程同时访问 Value 不会导致重复创建对象。C# 提供了多种线程安全模式:

  • LazyThreadSafetyMode.ExecutionAndPublication:默认模式,确保只有一个线程初始化,其他等待。
  • LazyThreadSafetyMode.None:不保证线程安全,性能更高,适合单线程场景。
  • LazyThreadSafetyMode.PublicationOnly:允许多个线程同时初始化,但只保留第一个结果。

// 禁用线程安全 var lazyNoSync = new Lazy(() => new ExpensiveObject(),      LazyThreadSafetyMode.None);

应用场景示例

常见于以下情况:

  • 加载大型配置对象,但程序运行中未必会用到。
  • 创建数据库连接或文件读取器,避免提前占用资源。
  • 在属性中封装延迟加载逻辑。

public class ServiceManager {     private readonly Lazy _logger = new Lazy(() => new Logger("log.txt")); 
public Logger GetLogger() {     return _logger.Value; // 需要时才创建日志器 }

}

基本上就这些。Lazy 让延迟初始化变得简洁、安全且可控,是优化资源使用的好工具

text=ZqhQzanResources