当前位置: 首页 > news >正文

C#Lazy

Lazy<T>是一个用于实现延迟初始化(Lazy Initialization)的泛型类,它可以将昂贵对象的创建推迟到第一次实际使用时。这种模式能有效提升应用程序的启动性能和资源利用率。

💡 核心概念与价值

Lazy<T>的核心思想是“按需创建”。它特别适用于以下场景:

  • 资源密集型对象:创建成本高、耗时长的对象,如加载大型文件、建立数据库连接或进行复杂计算。

  • 可能不被使用的对象:某些功能或组件在程序运行过程中可能根本不会被访问,使用 Lazy<T>可以避免不必要的初始化开销。

  • 提升启动速度:通过将非核心资源的初始化后移,让应用程序更快启动。

 

使用Lazy<T>时,需要注意以下几点:

  1. 线程安全:Lazy<T>默认是线程安全的,可以在多线程环境下使用,确保只有一个线程可以初始化实例。

  2. 初始化方式:可以通过传递一个委托来自定义初始化过程,如果不传递,则使用类型的默认构造函数。

  3. 异常处理:如果初始化过程中出现异常,则每次访问Value属性时都会抛出异常,除非重新初始化。

🛠️ 基本用法与示例

使用 Lazy<T>非常简单,其核心是通过访问 Value属性来触发初始化。

// 1. 基本用法:使用类型的默认构造函数
Lazy<ExpensiveObject> lazyObject1 = new Lazy<ExpensiveObject>();
// 在访问 Value 属性之前,ExpensiveObject 并不会被创建
ExpensiveObject obj1 = lazyObject1.Value;// 2. 使用委托自定义初始化逻辑
Lazy<ExpensiveObject> lazyObject2 = new Lazy<ExpensiveObject>(() => 
{// 这里可以编写复杂的初始化代码return new ExpensiveObject("自定义参数");
});ExpensiveObject obj2 = lazyObject2.Value;

 示例:模拟一个初始化昂贵的对象

public class ExpensiveService
{public ExpensiveService(){Console.WriteLine(">>> ExpensiveService 被创建了!这个过程很耗时...");// 模拟昂贵的初始化操作,如读取大文件或连接数据库Thread.Sleep(2000); }public void DoWork() => Console.WriteLine("正在工作...");
}class Program
{static void Main(){Console.WriteLine("程序开始...");// 创建 Lazy 实例,但昂贵的对象尚未初始化Lazy<ExpensiveService> lazyService = new Lazy<ExpensiveService>();Console.WriteLine("Lazy 对象已创建,但 ExpensiveService 还未初始化。");// 第一次访问 .Value 属性,触发实际创建Console.WriteLine("首次访问 lazyService.Value...");lazyService.Value.DoWork(); // 此时会看到构造函数中的输出// 后续访问将直接返回已创建好的实例,不会再次初始化Console.WriteLine("再次访问 lazyService.Value...");lazyService.Value.DoWork();}
}

 输出结果:

程序开始...
Lazy 对象已创建,但 ExpensiveService 还未初始化。
首次访问 lazyService.Value...
>>> ExpensiveService 被创建了!这个过程很耗时...
正在工作...
再次访问 lazyService.Value...
正在工作...

 从输出可以看出,ExpensiveService的构造函数只在第一次访问 .Value时被调用了一次。

 

🔒 线程安全模式

Lazy<T>的一个重要优势是内置了对多线程环境的支持。你可以通过 LazyThreadSafetyMode枚举来指定不同的线程安全行为。

// 1. ExecutionAndPublication (默认模式,最安全)
// 确保只有一个线程能执行初始化,初始化后所有线程都看到同一个实例。
Lazy<ExpensiveObject> safeLazy = new Lazy<ExpensiveObject>(() => new ExpensiveObject(),LazyThreadSafetyMode.ExecutionAndPublication
);// 2. PublicationOnly
// 允许多个线程同时执行初始化,但只采用第一个成功初始化的结果,适合初始化成本极高且可接受短暂资源浪费的场景。
Lazy<ExpensiveObject> publicationLazy = new Lazy<ExpensiveObject>(() => new ExpensiveObject(),LazyThreadSafetyMode.PublicationOnly
);// 3. None
// 非线程安全,性能最高,但仅适用于单线程环境。
Lazy<ExpensiveObject> unsafeLazy = new Lazy<ExpensiveObject>(() => new ExpensiveObject(),LazyThreadSafetyMode.None
);

📚 实际应用场景

  1. 实现单例模式(Singleton)

    这是 Lazy<T>最经典的应用之一,它能以简洁且线程安全的方式实现延迟加载的单例。

    public sealed 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<T>确保只在需要时才加载。

    public class ImageLoader
    {private Lazy<Bitmap> _lazyImage = new Lazy<Bitmap>(() => (Bitmap)Image.FromFile("path/to/large_image.jpg"));public Bitmap GetImage() => _lazyImage.Value;
    }

     

  3. 在依赖注入中使用

    在现代应用开发中,依赖注入容器也广泛利用延迟加载来优化服务启动时间。

  4. ⚠️ 注意事项与最佳实践

    • 异常处理:如果初始化委托(valueFactory)中抛出异常,Lazy<T>会缓存这个异常。之后每次访问 Value属性都会再次抛出相同的异常。因此,务必确保初始化逻辑的健壮性,或在委托内进行适当的异常处理。

    • 避免过度使用:只有在对象确实创建昂贵或可能不被使用时才考虑使用 Lazy<T>。不必要的包装会增加代码复杂性并带来微小的性能开销。

    • 检查是否已初始化:可以通过 IsValueCreated属性来检查对象是否已经被初始化,这在某些调试或特定逻辑中很有用。

    • if (lazyObject.IsValueCreated)
      {Console.WriteLine("对象已经初始化了。");
      }

       

http://www.jsqmd.com/news/43579/

相关文章:

  • 加氢站安全监测选型:别让传感器成为你的定时炸弹
  • linux anaconda
  • 服务器接口调用微信小程序获取手机号接口报:The SSL connection could not be established, see inner exception.
  • 事倍功半是蠢蛋62 docker 语句儿生产力
  • 【重磅升级!迅为iTOP-Hi3403开发板SDK全面升级至Linux 6.6内核】
  • 2025留学美国被开除怎么办?申诉挽回/学业急救/身份保留/转学规划/签证补救机构哪家强
  • 2025年国内档案馆展示柜厂家综合实力排行榜TOP10
  • 2025年陕西省探矿权采矿权技术服务企业权威推荐榜单
  • WPS用Qt还情有可原
  • C#技术
  • 2025年山西口碑好的纪念馆展示柜厂家十大排名权威推荐
  • 2025年评价高的UV 软膜广告灯箱厂家最新TOP排行
  • 2025年山西口碑好的纪念馆展示柜定制厂家排行Top10推荐
  • C# 14 新功能全面解析:提升生产力与性能的革命性更新
  • 【隐语SecretFlow隐私计算】如何使用 Kuscia API 运行一个 SecretFlow Serving
  • 2025年优秀的软件行业体系认证三体系认证品牌实力推荐榜
  • linux ajax
  • linux adobe reader
  • 2025年11月中国香菇品牌排名
  • 2025年11月中国枸杞企业口碑推荐榜单
  • 2025留学开除申诉机构推荐Top5,学术诚信申诉/退学申诉全流程护航
  • 机器视觉:智能车大赛视觉组手艺文档——用 YOLO3 Nano 实现目标检测并部署到 OpenART
  • C#重要的数据结构
  • 学业危机速看!2025美国紧急转学机构哪家好,学分对接/院校适配全解析
  • 探索Word2Vec:从文本向量化到中文语料处理 - 指南
  • Sandboxie-Plus 为沙盒运行的软件创建快捷方式
  • 基于DeepSeek-R1 15b微调训练自主的领域大模型,附带工程代码
  • 意识流计网原笔记(超级抱佛脚版)
  • 【理论知识】Q/K/V权重矩阵学习笔记 - 指南
  • CF2161D题解