C#性能优化技巧:利用Lazy<T>实现集合元素的延迟加载

ops/2025/1/23 12:07:51/

一、C#中的Lazy

C#中的Lazy<T>是一个泛型类,它实现了延迟加载(Lazy Initialization)的功能。延迟加载是指对象的创建被推迟,直到第一次被使用时才进行实例化。这对于大型或资源密集型对象的性能优化非常有用,因为它可以避免不必要的初始化和资源消耗。

二、Lazy与集合结合使用实现延迟加载

Lazy<T>可以与集合结合使用,以实现集合元素的延迟加载。这通常用于那些初始化代价较高或不需要立即初始化的集合元素。以下是实现这一功能的步骤和示例:

  1. 声明Lazy集合

    首先需要声明一个Lazy<T>类型的集合,其中T是集合元素的类型。这个集合将包含延迟加载的元素。

    Lazy<List<ExpensiveObject>> lazyObjectList = new Lazy<List<ExpensiveObject>>(() => CreateExpensiveObjectList());
    

    在这个例子中,ExpensiveObject是一个大型或资源密集型的对象,CreateExpensiveObjectList是一个返回List<ExpensiveObject>的方法,该方法包含创建和初始化这些对象的逻辑。

  2. 访问Lazy集合

    需要访问集合中的元素时,可以通过Lazy<T>实例的Value属性来获取集合。这是第一次访问时,集合的元素才会被创建和初始化。

    List<ExpensiveObject> objectList = lazyObjectList.Value;
    

    在这个例子中,第一次访问lazyObjectList.Value时,CreateExpensiveObjectList方法会被调用,并且返回一个List<ExpensiveObject>实例。之后的所有访问都将返回这个已经创建的实例,而不会再次调用CreateExpensiveObjectList方法。

  3. 线程安全性

    默认情况下,Lazy<T>是线程安全的。这意味着在多线程环境中,只有一个线程会执行初始化代码,从而避免不必要的资源消耗和竞争条件。然而,也可以通过指定LazyThreadSafetyMode枚举值来自定义线程安全行为。

    Lazy<List<ExpensiveObject>> lazyObjectList = new Lazy<List<ExpensiveObject>>(() => CreateExpensiveObjectList(), LazyThreadSafetyMode.ExecutionAndPublication);
    

    在这个例子中,我们指定了LazyThreadSafetyMode.ExecutionAndPublication模式,这保证了初始化过程和发布过程都是线程安全的。

三、示例代码

以下是一个完整的示例代码,展示了如何使用Lazy<T>与集合结合实现延迟加载:

using System;
using System.Collections.Generic;class ExpensiveObject
{public ExpensiveObject(){// 模拟一个初始化代价很昂贵的操作Console.WriteLine("Expensive object initialized.");}
}class Program
{static void Main(string[] args){// 使用Lazy<T>创建一个延迟加载的集合Lazy<List<ExpensiveObject>> lazyObjectList = new Lazy<List<ExpensiveObject>>(() => CreateExpensiveObjectList());// 在需要时访问集合Console.WriteLine("访问list...");List<ExpensiveObject> objectList = lazyObjectList.Value;// 使用集合中的元素foreach (var obj in objectList){// 这里可以对obj进行操作}Console.ReadKey();}static List<ExpensiveObject> CreateExpensiveObjectList(){// 创建一个包含多个ExpensiveObject的列表List<ExpensiveObject> list = new List<ExpensiveObject>();for (int i = 0; i < 10; i++){list.Add(new ExpensiveObject());}return list;}
}

在这个示例中,当运行程序时,会看到在第一次访问lazyObjectList.Value时输出了“Expensive object initialized.”,表示ExpensiveObject实例被创建了。之后的所有访问都不会再次输出这个信息,因为集合已经被初始化了。


http://www.ppmy.cn/ops/152459.html

相关文章

计算机视觉中的目标检测技术

1. 引言 目标检测是计算机视觉中的重要任务&#xff0c;涉及识别图像或视频中的多个对象并定位它们的位置。与图像分类不同&#xff0c;目标检测不仅需要识别类别&#xff0c;还要在图像中绘制出对象的边界框(Bounding Box)。本文将探讨目标检测的核心技术和应用&#xff0c;并…

STM32 GPIO工作模式

GPIO工作模式 1. GPIO简介2. GPIO工作模式2.1 输入浮空2.2 输入上拉2.3 输入下拉2.4 模拟2.5 开漏输出2.6 推挽输出2.7 开漏式复用功能2.8 推挽式复用功能 1. GPIO简介 GPIO 是通用输入输出端口的简称&#xff0c;简单来说就是 STM32 可控制的引脚&#xff0c;STM32 芯片的 GPI…

2、ceph的安装——方式二ceph-deploy

一、ceph部署 1、更新yum源 wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo2、下载 pip yum -y install python-pip3、始终同步、关闭防火墙、selinux、三台机器做免密 yum install -y ntpdate ntpdate ntp.aliyun.com setenforce 0…

【Golang 面试题】每日 3 题(四十一)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

封装 调用第三方链接接口

function payOutCardInfo($card_id,$amount) {$url config(payOut.url).v1/cash-out/card-info;$headers [accept: */*,Content-Type: application/json];//$data [cardId > $card_id,amount > $amount,];// 将数据转换为JSON格式$jsonData json_encode($data);// 初…

C# 动态创建Label和ComboBox控件并修改Text获取Text

背景&#xff1a;在做项目的时候可能需要根据一定数量创建某些控件并修改其属性&#xff0c;本文以控件label、ConboBox控件进行动态创建。 程序运行前后的的Form动态图 代码如下&#xff1a; using System; using System.Collections.Generic; using System.ComponentModel; …

自动化标注平台开源,基于 yolov8标注平台可本地部署

yolov8标注平台本地部署&#xff08;docker部署&#xff09;&#xff0c;已调通yolov8模型自动预标注功能。 下面开始背景知识…… 1&#xff09;数据标注为什么在人工智能时代如此重要&#xff1f; 数据标注在人工智能时代如此重要&#xff0c;原因如下&#xff1a; 为机器…

《自动驾驶与机器人中的SLAM技术》ch8:基于预积分和图优化的紧耦合 LIO 系统

目录 1 预积分 LIO 系统的经验 2 预积分图优化的顶点 3 预积分图优化的边 3.1 NDT 残差边&#xff08;观测值维度为 3 维的单元边&#xff09; 4 基于预积分和图优化 LIO 系统的实现 4.1 IMU 静止初始化 4.2 使用预积分预测 4.3 使用 IMU 预测位姿进行运动补偿 4.4 位姿配准部…