一、C#中的Lazy
C#中的Lazy<T>
是一個泛型類,它實現了延遲加載(Lazy Initialization)的功能。延遲加載是指對象的創建被推遲,直到第一次被使用時才進行實例化。這對于大型或資源密集型對象的性能優化非常有用,因為它可以避免不必要的初始化和資源消耗。
二、Lazy與集合結合使用實現延遲加載
Lazy<T>
可以與集合結合使用,以實現集合元素的延遲加載。這通常用于那些初始化代價較高或不需要立即初始化的集合元素。以下是實現這一功能的步驟和示例:
-
聲明Lazy集合:
首先需要聲明一個
Lazy<T>
類型的集合,其中T
是集合元素的類型。這個集合將包含延遲加載的元素。Lazy<List<ExpensiveObject>> lazyObjectList = new Lazy<List<ExpensiveObject>>(() => CreateExpensiveObjectList());
在這個例子中,
ExpensiveObject
是一個大型或資源密集型的對象,CreateExpensiveObjectList
是一個返回List<ExpensiveObject>
的方法,該方法包含創建和初始化這些對象的邏輯。 -
訪問Lazy集合:
需要訪問集合中的元素時,可以通過
Lazy<T>
實例的Value
屬性來獲取集合。這是第一次訪問時,集合的元素才會被創建和初始化。List<ExpensiveObject> objectList = lazyObjectList.Value;
在這個例子中,第一次訪問
lazyObjectList.Value
時,CreateExpensiveObjectList
方法會被調用,并且返回一個List<ExpensiveObject>
實例。之后的所有訪問都將返回這個已經創建的實例,而不會再次調用CreateExpensiveObjectList
方法。 -
線程安全性:
默認情況下,
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
實例被創建了。之后的所有訪問都不會再次輸出這個信息,因為集合已經被初始化了。