导读:本期聚焦于小伙伴创作的《C#如何实现泛型单例?C#基于Generic T的通用单例模式基类怎么写》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#如何实现泛型单例?C#基于Generic T的通用单例模式基类怎么写》有用,将其分享出去将是对创作者最好的鼓励。

在C#项目开发中,单例模式是高频使用的设计模式,传统实现方式需要为每个单例类单独编写实例获取、线程安全控制等逻辑,会产生大量冗余代码。通过泛型单例基类,我们可以把通用的单例逻辑抽象出来,让所有需要单例特性的类只需要继承该基类就能自动获得单例能力,大幅降低重复开发成本。

C#如何实现泛型单例?C#基于Generic T的通用单例模式基类怎么写

泛型单例基类的核心设计思路

要实现通用的泛型单例基类,首先需要明确几个核心约束:第一,泛型参数T必须是引用类型,避免值类型带来的装箱拆箱问题;第二,T必须有无参数的构造函数,这样基类才能自动创建实例;第三,需要处理多线程环境下的实例创建安全问题,避免多个线程同时创建实例导致单例失效。

基础泛型单例基类实现

我们先实现线程安全的基础版本,使用lock关键字保证实例创建的原子性,同时通过volatile关键字避免指令重排序带来的问题。

using System;

// 泛型单例基类,约束T为引用类型且无参构造函数
public abstract class SingletonBase<T> where T : class, new()
{
    // volatile保证多线程下实例的可见性,避免指令重排
    private static volatile T _instance;
    // 用于加锁的对象,静态对象保证所有线程共享同一个锁
    private static readonly object _lockObj = new object();

    // 受保护的构造函数,防止外部直接实例化
    protected SingletonBase() { }

    // 公开的实例获取属性
    public static T Instance
    {
        get
        {
            // 第一次检查,避免每次获取实例都加锁,提升性能
            if (_instance == null)
            {
                lock (_lockObj)
                {
                    // 第二次检查,避免多个线程同时通过第一次检查后重复创建实例
                    if (_instance == null)
                    {
                        _instance = new T();
                    }
                }
            }
            return _instance;
        }
    }
}

实际使用方式

需要单例的类只需要继承SingletonBase<T>,其中T就是当前类的类型,就可以直接通过Instance属性获取单例实例。

// 示例单例类,继承泛型单例基类
public class GameManager : SingletonBase<GameManager>
{
    // 受保护的构造函数,和基类约束匹配
    protected GameManager() { }

    // 自定义的业务方法
    public void InitGame()
    {
        Console.WriteLine("游戏管理器初始化完成");
    }
}

// 调用示例
class Program
{
    static void Main(string[] args)
    {
        // 直接通过Instance获取单例实例
        GameManager.Instance.InitGame();
        // 验证单例特性,两次获取的实例是同一个
        var instance1 = GameManager.Instance;
        var instance2 = GameManager.Instance;
        Console.WriteLine(instance1 == instance2); // 输出True
    }
}

进阶优化点

支持带参数的构造函数

上面的基础版本要求T必须有公共无参构造函数,如果单例类需要带参数的初始化逻辑,我们可以调整基类的实现,通过委托传入实例创建方法。

using System;

public abstract class SingletonBase<T> where T : class
{
    private static T _instance;
    private static readonly object _lockObj = new object();
    // 存储实例创建的委托
    private static Func<T> _createInstanceFunc;

    protected SingletonBase() { }

    // 初始化单例创建方法的静态方法,需要在第一次获取实例前调用
    public static void SetCreateInstanceFunc(Func<T> createFunc)
    {
        _createInstanceFunc = createFunc;
    }

    public static T Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (_lockObj)
                {
                    if (_instance == null)
                    {
                        if (_createInstanceFunc == null)
                        {
                            throw new InvalidOperationException("未设置单例实例创建方法");
                        }
                        _instance = _createInstanceFunc();
                    }
                }
            }
            return _instance;
        }
    }
}

// 带参数构造函数的单例类示例
public class ConfigManager : SingletonBase<ConfigManager>
{
    private string _configPath;

    // 私有构造函数,参数通过创建委托传入
    private ConfigManager(string configPath)
    {
        _configPath = configPath;
    }

    public string GetConfigPath()
    {
        return _configPath;
    }
}

// 调用示例
class Program
{
    static void Main(string[] args)
    {
        // 先设置实例创建委托,传入构造参数
        ConfigManager.SetCreateInstanceFunc(() => new ConfigManager("config/app.json"));
        // 获取单例实例
        var configPath = ConfigManager.Instance.GetConfigPath();
        Console.WriteLine(configPath); // 输出config/app.json
    }
}

避免单例被继承滥用

如果希望泛型单例基类只能被指定的类继承,或者避免用户随意继承基类,我们可以把基类的构造函数设置为private,同时结合嵌套类的方式实现更严格的约束,不过这种方式会稍微增加代码复杂度,实际开发中可以根据项目需求选择是否添加。

注意事项

  • 泛型单例基类中的静态实例是和泛型参数T绑定的,不同的T类型会对应不同的静态实例,不会互相干扰。
  • 如果单例类需要在程序退出时释放资源,可以在基类中添加Dispose方法,手动释放实例引用。
  • 不要在单例类的构造函数中做太多耗时的初始化操作,避免第一次获取实例时阻塞调用线程。
  • 如果项目使用依赖注入框架,建议优先使用框架提供的单例注册方式,泛型单例基类更适合没有引入重量级框架的小型项目。

C#泛型单例Generic_T单例模式基类通用单例修改时间:2026-07-03 15:06:27

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