c# 设计模式有哪些 c#单例模式怎么写

12次阅读

C#单例模式有多种实现,推荐Lazy+readonly字段方案,线程安全且支持延迟初始化;Static class无法替代,因其不支持接口继承泛型约束、IDisposable及按需初始化。

c# 设计模式有哪些 c#单例模式怎么写

单例模式在 C# 中不是“只有一种写法”,而是有多个变体,各自适用于不同场景;选错实现方式,轻则线程不安全,重则引发内存泄漏或初始化异常。

为什么不能直接用 static class 替代 Singleton?

static class 看似简单,但它无法实现接口、不能被继承、不能作为泛型约束类型参数,更关键的是——它会在程序集加载时立即初始化所有静态字段,哪怕你根本没用到它。而真正的单例应支持延迟初始化(lazy initialization)。

  • static class 无法实现 IDisposable,资源释放不可控
  • 单元测试时难以 mock 或替换依赖
  • 若构造逻辑含副作用(如读配置、连数据库),提前触发会拖慢启动速度

C# 最推荐的单例写法:Lazy + readonly 字段

这是 .net 4.0+ 下线程安全、延迟加载、简洁可靠的首选方案。CLR 保证 Lazy 的初始化是线程安全的,且只执行一次。

public sealed class Logger {     private static readonly Lazy _instance = new Lazy(() => new Logger()); 
public static Logger Instance => _instance.Value;  private Logger() { } // 私有构造,防止外部 new

}

  • Lazy 默认使用 LazyThreadSafetyMode.ExecutionAndPublication,无需额外加锁
  • 构造函数保持 private,杜绝反射绕过(若需更强防护,可在构造中加 if (Interlocked.Increment(ref _initCount) != 1) throw
  • 不建议在 Instance getter 中做复杂逻辑,否则每次访问都可能触发隐式开销

什么时候该用双重检查锁定(double-Checked Locking)?

仅当你需要在 .NET 3.5 或更早版本运行,或必须控制初始化时机(比如要传参给构造函数),才考虑 DCL。它容易写错,常见坑包括:

  • 忘记用 volatile 修饰实例字段,导致其他线程看到未完全构造的对象
  • lock 对象不是私有静态字段,造成锁粒度失控
  • 在 lock 外部再次判空时,用了非 volatile 字段,引发重排序问题
public sealed class ConfigLoader {     private static volatile ConfigLoader _instance;     private static readonly object _lock = new object(); 
public static ConfigLoader Instance {     get     {         if (_instance == null)         {             lock (_lock)             {                 if (_instance == null)                     _instance = new ConfigLoader();             }         }         return _instance;     } }  private ConfigLoader() { }

}

Async 初始化的单例怎么处理?

如果构造过程需要异步操作(如从文件/网络加载配置),Lazy 不适用(它不支持 async 工厂)。此时应改用 AsyncLazy(需自行实现或引用 microsoft.visualstudio.Threading)。

  • 不要在属性 getter 中直接 await —— 属性不能是 async
  • 暴露 Task 类型的静态成员(如 InstanceAsync),调用方负责 await
  • 注意首次 await 可能阻塞,后续调用返回已完成 Task

真正难的不是写出一个“能跑”的单例,而是判断它是否该存在——大多数时候,你真正需要的是依赖注入容器(如 Microsoft.Extensions.DependencyInjection)管理生命周期,而不是手写单例。

text=ZqhQzanResources