C#怎么实现单例模式

来源:AI社区作者:菲律宾程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《C#怎么实现单例模式》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#怎么实现单例模式》有用,将其分享出去将是对创作者最好的鼓励。

单例模式是设计模式中最基础也最常用的模式之一,在C#开发中,实现单例模式需要兼顾线程安全、实例唯一性和访问便捷性等多个维度,不同的实现方式对应不同的使用场景。

C#怎么实现单例模式

C#单例模式的核心要求

一个标准的单例模式实现需要满足三个核心条件:

  • 类的构造方法必须是私有的,防止外部通过new关键字创建实例
  • 类内部需要维护一个自身的静态实例
  • 提供一个公共的静态方法或者属性,用于外部获取唯一的实例

常见的C#单例实现方法

1. 饿汉式单例

饿汉式单例是在类加载时就直接创建实例,实现简单且线程安全,但是会提前占用内存。

public class HungrySingleton
{
    // 类加载时就初始化实例
    private static readonly HungrySingleton instance = new HungrySingleton();
    
    // 私有构造方法,防止外部实例化
    private HungrySingleton() { }
    
    // 公共访问点
    public static HungrySingleton Instance
    {
        get { return instance; }
    }
    
    // 示例方法
    public void DoSomething()
    {
        Console.WriteLine("饿汉式单例执行方法");
    }
}

2. 简单懒汉式单例(非线程安全)

懒汉式单例是在第一次调用获取实例的方法时才创建实例,但是这种基础实现方式在多线程环境下会出现多个实例的问题。

public class LazySingletonUnsafe
{
    private static LazySingletonUnsafe instance = null;
    
    private LazySingletonUnsafe() { }
    
    public static LazySingletonUnsafe Instance
    {
        get
        {
            // 多线程同时进入这里时,可能会创建多个实例
            if (instance == null)
            {
                instance = new LazySingletonUnsafe();
            }
            return instance;
        }
    }
}

3. 双重检查锁定单例

双重检查锁定是懒汉式单例的线程安全优化版本,既保证了线程安全,又减少了锁的开销,适合多线程场景。

public class DoubleCheckSingleton
{
    // 使用volatile关键字保证多线程下变量的可见性
    private static volatile DoubleCheckSingleton instance = null;
    // 线程锁对象
    private static readonly object lockObj = new object();
    
    private DoubleCheckSingleton() { }
    
    public static DoubleCheckSingleton Instance
    {
        get
        {
            // 第一次检查,避免不必要的锁开销
            if (instance == null)
            {
                lock (lockObj)
                {
                    // 第二次检查,确保只有一个实例被创建
                    if (instance == null)
                    {
                        instance = new DoubleCheckSingleton();
                    }
                }
            }
            return instance;
        }
    }
}

4. 静态内部类单例

利用C#静态内部类的特性,只有在调用内部类的静态成员时才会加载内部类,从而实现懒加载和线程安全,代码更简洁。

public class InnerClassSingleton
{
    private InnerClassSingleton() { }
    
    // 静态内部类,只有被调用时才会加载
    private static class SingletonHolder
    {
        internal static readonly InnerClassSingleton instance = new InnerClassSingleton();
    }
    
    public static InnerClassSingleton Instance
    {
        get { return SingletonHolder.instance; }
    }
}

5. 泛型单例基类

如果项目中多个类都需要实现单例模式,可以封装一个泛型单例基类,减少重复代码。

public abstract class GenericSingleton<T> where T : class
{
    private static T instance = null;
    private static readonly object lockObj = new object();
    
    protected GenericSingleton() { }
    
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                lock (lockObj)
                {
                    if (instance == null)
                    {
                        // 通过反射创建实例,要求T有私有构造方法
                        var constructor = typeof(T).GetConstructor(
                            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
                            null, Type.EmptyTypes, null);
                        if (constructor == null)
                        {
                            throw new InvalidOperationException("类型必须包含私有无参构造方法");
                        }
                        instance = constructor.Invoke(null) as T;
                    }
                }
            }
            return instance;
        }
    }
}

// 使用示例
public class UserService : GenericSingleton<UserService>
{
    private UserService() { }
    
    public void AddUser()
    {
        Console.WriteLine("添加用户");
    }
}

不同实现方式的对比

我们可以通过下表对比不同单例实现方式的特点,方便选择:

实现方式线程安全懒加载实现复杂度适用场景
饿汉式单例实例占用资源小,不需要懒加载的场景
简单懒汉式单线程环境,不需要线程安全的场景
双重检查锁定多线程环境,需要懒加载的场景
静态内部类多线程环境,需要懒加载且代码简洁的场景
泛型单例基类多个类需要实现单例,减少重复代码的场景

单例模式的使用注意事项

虽然单例模式使用广泛,但是也存在一些需要注意的问题:

  • 单例类的构造方法是私有的,所以无法被继承,也不方便进行单元测试,因为单例的状态是全局共享的
  • 如果单例实例持有大量资源,可能会导致内存占用过高,尤其是在应用程序生命周期很长的情况下
  • 不要过度使用单例模式,很多场景下可以通过依赖注入的方式管理对象生命周期,比单例模式更灵活

在实际开发中,推荐优先使用静态内部类或者双重检查锁定的方式实现单例,这两种方式兼顾了线程安全和懒加载的需求,适配大多数使用场景。如果是.NET 4.0及以上版本,还可以使用Lazy<T>类型来实现单例,进一步简化代码。

C#Singleton单例模式设计模式修改时间:2026-06-30 14:09:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。