C#中Lazy<T> 泛型类(延迟初始化对象)

在 C# 中,Lazy 是一个泛型类,用于延迟初始化对象。它提供了一种方便的方式来推迟对象的创建,直到首次访问该对象时。

Lazy 类有一个重要的特性,即它使用了线程安全的方式进行延迟初始化。这意味着即使在多线程环境下,多个线程同时访问 Lazy 对象,也只会有一个线程执行初始化操作,并且所有线程最终都会获取到相同的初始化结果。

下面是一个简单的示例,演示了如何使用 Lazy 来延迟初始化对象:

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 对象 lazyObject,用于延迟初始化 ExpensiveObject。当我们需要使用 ExpensiveObject 对象时,通过访问 lazyObject.Value 来触发对象的初始化。在初始化过程中,ExpensiveObject 的构造函数被调用。后续的访问中,我们可以直接使用已初始化的对象。

需要注意的是,Lazy 对象的初始化是延迟进行的,只有在首次访问 Value 属性时才会发生。如果初始化过程中发生异常,后续的访问会继续引发同样的异常。如果需要在初始化期间进行一些额外的逻辑处理,可以使用 Lazy 的构造函数重载或者通过 Lazy 的事件来实现。

Lazy 类是 C# 中一种方便且线程安全的机制,用于延迟初始化对象,并且在多线程环境中表现良好。它能够提高性能和资源利用率,只在需要时才创建和初始化对象。


Lazy 类在底层使用了 System.Threading.Lazy 类来实现延迟初始化的功能。System.Threading.Lazy 类是 .NET Framework 提供的线程安全的延迟初始化类。

System.Threading.Lazy 类使用了一种名为双重检查锁定(double-checked locking)的模式来确保只有一个线程执行初始化操作,并且其他线程在初始化完成之前会等待。这种模式结合了性能和线程安全性。

下面是 System.Threading.Lazy 类的简化版本的概念实现:

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 类包含了一个私有变量 value 用于存储延迟初始化后的值。valueFactory 是一个委托,用于在首次访问 Value 属性时进行对象的初始化操作。isValueCreated 标记了是否已经创建了 value

当首次访问 Value 属性时,会先进行一个快速的检查,如果 isValueCreatedfalse,则进入锁定的代码块。在锁定的代码块内,再次检查 isValueCreated,以防止其他线程已经初始化了对象。如果 isValueCreated 仍为 false,则使用 valueFactory 委托创建对象,并将其赋值给 value。最后,将 isValueCreated 设置为 true,表示对象已经创建。

在多线程环境下,多个线程同时访问 Value 属性时,只有一个线程能够通过双重检查锁定的方式执行初始化操作,其他线程会等待初始化完成。这种方式保证了线程安全性,并且只有在需要时才进行初始化操作,避免了不必要的开销。

需要注意的是,System.Threading.Lazy 类还提供了其他重载的构造函数和属性,使您可以自定义初始化过程、指定线程安全性等。这些细节在实际使用时可以根据需求进行调整。

总而言之,Lazy 类在底层使用了 System.Threading.Lazy 类来实现延迟初始化的功能。它使用双重检查锁定模式确保线程安全,并提供了方便的机制来推迟对象的创建,只在需要时才进行初始化。

你可能感兴趣的:(学习C#的笔记,c#,开发语言)