在 C# 中,Lazy<T>
是一个泛型类,用于延迟初始化对象。它提供了一种方便的方式来推迟对象的创建,直到首次访问该对象时。
Lazy<T>
类有一个重要的特性,即它使用了线程安全的方式进行延迟初始化。这意味着即使在多线程环境下,多个线程同时访问 Lazy<T>
对象,也只会有一个线程执行初始化操作,并且所有线程最终都会获取到相同的初始化结果。
下面是一个简单的示例,演示了如何使用 Lazy<T>
来延迟初始化对象:
class Program
{static void Main(string[] args){Lazy<ExpensiveObject> lazyObject = new Lazy<ExpensiveObject>();// 当需要访问 ExpensiveObject 对象时,进行初始化ExpensiveObject expensiveObject = lazyObject.Value;// 后续访问时,直接使用已初始化的对象expensiveObject.DoSomething();}
}class ExpensiveObject
{public ExpensiveObject(){// 对象的初始化操作Console.WriteLine("ExpensiveObject is being initialized.");}public void DoSomething(){Console.WriteLine("ExpensiveObject is doing something.");}
}
在上述示例中,ExpensiveObject
是一个代表昂贵对象的类。在 Main
方法中,我们创建了一个 Lazy<ExpensiveObject>
对象 lazyObject
,用于延迟初始化 ExpensiveObject
。当我们需要使用 ExpensiveObject
对象时,通过访问 lazyObject.Value
来触发对象的初始化。在初始化过程中,ExpensiveObject
的构造函数被调用。后续的访问中,我们可以直接使用已初始化的对象。
需要注意的是,Lazy<T>
对象的初始化是延迟进行的,只有在首次访问 Value
属性时才会发生。如果初始化过程中发生异常,后续的访问会继续引发同样的异常。如果需要在初始化期间进行一些额外的逻辑处理,可以使用 Lazy<T>
的构造函数重载或者通过 Lazy<T>
的事件来实现。
Lazy<T>
类是 C# 中一种方便且线程安全的机制,用于延迟初始化对象,并且在多线程环境中表现良好。它能够提高性能和资源利用率,只在需要时才创建和初始化对象。
Lazy<T>
类在底层使用了 System.Threading.Lazy<T>
类来实现延迟初始化的功能。System.Threading.Lazy<T>
类是 .NET Framework 提供的线程安全的延迟初始化类。
System.Threading.Lazy<T>
类使用了一种名为双重检查锁定(double-checked locking)的模式来确保只有一个线程执行初始化操作,并且其他线程在初始化完成之前会等待。这种模式结合了性能和线程安全性。
下面是 System.Threading.Lazy<T>
类的简化版本的概念实现:
class Lazy<T>
{private T value;private Func<T> valueFactory;private bool isValueCreated;private object lockObject = new object();public Lazy(Func<T> valueFactory){this.valueFactory = valueFactory;}public T Value{get{if (!isValueCreated){lock (lockObject){if (!isValueCreated){value = valueFactory();isValueCreated = true;}}}return value;}}
}
在上述简化的实现中,Lazy<T>
类包含了一个私有变量 value
用于存储延迟初始化后的值。valueFactory
是一个委托,用于在首次访问 Value
属性时进行对象的初始化操作。isValueCreated
标记了是否已经创建了 value
。
当首次访问 Value
属性时,会先进行一个快速的检查,如果 isValueCreated
为 false
,则进入锁定的代码块。在锁定的代码块内,再次检查 isValueCreated
,以防止其他线程已经初始化了对象。如果 isValueCreated
仍为 false
,则使用 valueFactory
委托创建对象,并将其赋值给 value
。最后,将 isValueCreated
设置为 true
,表示对象已经创建。
在多线程环境下,多个线程同时访问 Value
属性时,只有一个线程能够通过双重检查锁定的方式执行初始化操作,其他线程会等待初始化完成。这种方式保证了线程安全性,并且只有在需要时才进行初始化操作,避免了不必要的开销。
需要注意的是,System.Threading.Lazy<T>
类还提供了其他重载的构造函数和属性,使您可以自定义初始化过程、指定线程安全性等。这些细节在实际使用时可以根据需求进行调整。
总而言之,Lazy<T>
类在底层使用了 System.Threading.Lazy<T>
类来实现延迟初始化的功能。它使用双重检查锁定模式确保线程安全,并提供了方便的机制来推迟对象的创建,只在需要时才进行初始化。