首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

深入 .NET 4.0:Lazy<T> 延遲初始化完全指南

     編輯:關於.NET

物件的建立方式始終反映了軟體工業的生產力方向,也代表了先進軟體技術演進的軌跡。從直接使用 new、工廠模式,到 IoC 容器,各種模式都在解決實例建立的問題。而 .NET 4.0 引入的 System.Lazy<T>,則專注於「按需建立」而非「按時建立」,為延遲初始化提供了標準化、執行緒安全的解決方案。

為什麼需要 Lazy<T>?

在實際開發中,常會遇到某些關聯物件建立成本極高(如大量記憶體配置、資料庫連線、複雜運算)的情況。若在程式啟動時就建立這些物件,會嚴重拖慢啟動速度並浪費資源。傳統做法需開發者自行實作「懶惰物件」模式(參考老趙的《延遲代理的編寫方式》),但 .NET 4.0 內建的 Lazy<T> 讓這一切變得標準且簡單。

核心類別定義

[Serializable]
public class Lazy<T>
{
    public Lazy();
    public Lazy(bool isThreadSafe);
    public Lazy(Func<T> valueFactory);
    public Lazy(Func<T> valueFactory, bool isThreadSafe);

    public bool IsValueCreated { get; }
    public T Value { get; }

    public override string ToString();
}

註:本文基於 VS2010 Beta2 版本,最終正式版可能有細微差異。

基本用法:預設建構函式

假設有一個資源佔用大的 Big 類別:

public class Big
{
    public int ID { get; set; }
    // 其他昂貴資源...
}

使用 Lazy<Big> 包裝,實例只在首次存取 Value 屬性時才會建立:

static void Main(string[] args)
{
    Lazy<Big> lazyBig = new Lazy<Big>();
    // 此時 Big 尚未建立
    Console.WriteLine(lazyBig.Value.ID); // 首次存取,觸發建立
}

進階場景:自訂建構邏輯

若 Big 沒有無參數建構函式,例如:

public class Big
{
    public Big(int id) { this.ID = id; }
    public int ID { get; set; }
}

直接使用 new Lazy<Big>() 會拋出異常。此時應使用接受 Func<T> 的建構函式:

static void Main(string[] args)
{
    // 使用 Lambda 表達式指定建立邏輯
    Lazy<Big> lazyBig = new Lazy<Big>(() => new Big(100));
    Console.WriteLine(lazyBig.Value.ID); // 輸出 100
}

這個工廠委派可以整合任何複雜的建立邏輯,包括物件工廠、IoC 容器解析等:

public class BigFactory
{
    public static Big Build() => new Big(100);
}

// 使用工廠方法
Lazy<Big> lazyBig = new Lazy<Big>(() => BigFactory.Build());

執行緒安全控制

Lazy<T> 提供了兩個帶 isThreadSafe 參數的建構函式:

  • public Lazy(bool isThreadSafe)
  • public Lazy(Func<T> valueFactory, bool isThreadSafe)

當 isThreadSafe = true(預設值)時,確保多執行緒環境下物件只會被建立一次;設為 false 則移除鎖定機制,效能略高但需開發者自行保證單執行緒存取。

實用屬性:IsValueCreated

透過 IsValueCreated 唯讀屬性,可隨時檢查實例是否已經被建立,避免不必要的觸發:

if (!lazyBig.IsValueCreated)
{
    // 執行某些預備工作...
}
var instance = lazyBig.Value;

設計考量與最佳實踐

Lazy<T> 的應用不僅是語法層面,更涉及架構設計:

  • 整體物件延遲:適用於昂貴的服務、連線、大型資料結構。
  • 層級延遲:搭配屬性實現細粒度的延遲載入。
  • 執行緒安全選擇:預設安全模式適用於大多數情境;高效能單執行緒場景可關閉。

善用 Lazy<T> 能讓資源管理更具彈性,是 .NET 4.0 中不可或缺的工具類別。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved