You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助Lazy<T>的IsValueCreated确保C#单例模式唯一性?

关于Lazy<T>单例中IsValueCreated的用法

我读过Jon Skeet撰写的一篇关于单例模式的文章,其中他介绍了用Lazy<T>实现单例的写法,代码如下:

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
}

文章末尾提到:

它还允许你通过IsValueCreated属性检查实例是否已创建(如果有需要的话)。

IsValueCreated用于标记延迟对象是否完成初始化。我想知道,为了确保这个类始终保持单例(仅创建一个实例),应该在什么场景、怎么使用IsValueCreated属性?


核心结论

首先明确:这个基于Lazy<T>的单例实现本身已经保证了只会创建一个实例——Lazy<T>默认采用LazyThreadSafetyMode.ExecutionAndPublication线程安全模式,无论多少线程同时访问Instance属性,都只会触发一次实例化逻辑。IsValueCreated并不是用来"确保单例"的工具,它的核心作用是在不触发实例化的前提下,查询单例是否已经被初始化。

适用场景与具体用法

  • 避免不必要的实例化:如果有业务逻辑不需要获取单例实例,但需要根据实例是否存在做分支处理,就可以用IsValueCreated。比如:

    // 仅判断实例状态,不触发初始化
    if (Singleton.IsInstanceCreated)
    {
        // 实例已存在时的逻辑:比如记录运行状态、清理临时关联资源
        Log.Info("单例实例已完成初始化");
    }
    else
    {
        // 实例未初始化时的逻辑:比如提前加载依赖资源、提示前置条件
        PreloadRequiredResources();
    }
    

    注意:不要试图用IsValueCreated阻止实例化——只要访问Instance属性,Lazy<T>就会自动触发实例化流程。

  • 调试与监控:在排查问题或监控系统状态时,IsValueCreated可以快速帮你确认单例的初始化状态,比如输出调试日志:

    Debug.WriteLine($"单例实例状态:{(Singleton.IsInstanceCreated ? "已初始化" : "未初始化")}");
    

单例正确性的保障要点

要确保这个类始终是单例,你只需要维持以下设计:

  1. 类标记为sealed,防止被继承后通过子类创建新实例
  2. 构造函数设为private,禁止外部直接实例化
  3. 不要通过反射等手段破坏Lazy<T>或单例类的封装

IsValueCreated只是一个状态查询工具,和单例的正确性没有直接关联——单例的唯一性是由Lazy<T>的线程安全机制原生保证的。


内容的提问来源于Stack Exchange,提问作者OpenStack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 11:40:52