3.单例模式问题1:构造函数

一、C# 构造函数与单例模式安全性

1. 单例模式存在的问题

复制代码
public class Singleton<T> where T : class, new()
{
    private static T instance;
    public static T Instance
    {
        get
        {
            instance ??= new T();
            return instance;
        }
    }
}

通过new T()创建实例。但是这种方式存在一个问题:外部代码可以直接 new 单例对象,破坏单例唯一性

二、限制外部创建对象

1. 私有构造函数

解决方式:将构造函数设置为private

这样外部无法:new GameManager();

只能:GameManager.Instance来获取对象。

三、私有构造函数带来的问题

如果单例基类中:instance = new T();

要求:where T : new()

但是:私有构造函数不能满足 new() 约束,二者冲突了。

四、通过反射创建私有构造函数对象

解决方式:取消new()约束,改为where T : class,然后通过反射调用私有构造函数。

复制代码
using System;
using System.Reflection;

public abstract class Singleton<T> where T : class
{
    private static T instance;
    public static T Instance
    {
        get
        {
            if(instance == null)
            {
                Type type = typeof(T);
                ConstructorInfo constructor =type.GetConstructor(
                        BindingFlags.Instance | BindingFlags.NonPublic,
                        null,
                        Type.EmptyTypes,
                        null
                    );
                if(constructor != null)
                {
                    instance = constructor.Invoke(null) as T;
                }
            }
            return instance;
        }
    }
}

五、反射获取构造函数

Type

获取类型信息:typeof(T)

GetConstructor()

获取指定构造函数:type.GetConstructor();

参数:BindingFlags.Instance | BindingFlags.NonPublic

表示:实例构造函数 | private 构造函数

Type.EmptyTypes

无参数构造函数。

Invoke()

执行获取到的构造函数:

复制代码
constructor.Invoke(null)

六、为什么单例需要私有构造函数

单例设计目标:只能由内部创建,外部禁止创建

七、注意事项

  • 单例需要防止外部直接创建对象
  • 私有构造函数可以保证唯一性
  • 使用反射可以调用私有构造函数
  • 反射相比直接 new 有额外性能开销,但单例创建次数极少,影响可以忽略
  • 单例主要解决全局唯一对象管理问题,不应该所有类都使用
相关推荐
dialect_18 小时前
KMP算法
开发语言·c++·算法
总要学点什么19 小时前
第89篇:三维特效-螺旋圆效果——让螺旋臂卷起一圈圈外扩的涟漪
开发语言·javascript·ecmascript·webgl·cesium·空间分析·1024程序员节
开开心心_Every20 小时前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea
chenbingjie_c20 小时前
C++ 多态完全指南:从虚函数重写到虚函数表原理
开发语言·c++
吴卫斌20 小时前
定投ETF实战指南(四):行业/主题ETF——定投的“进攻端“
开发语言·python·股票·量化
超级架构师21 小时前
PRAXO-CORE 2.5.0:用 conformance 和显式边界构建 Go Agent 框架
开发语言·人工智能·后端·golang·ai编程·智能体框架·praxo-core
叼烟扛炮1 天前
Linux 学习笔记(四十三):网络编程进阶——自定义协议解决 TCP 粘包与守护进程
linux·开发语言·网络·笔记·tcp/ip
LMT流氓兔1 天前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节
专注仿真1 天前
梯度提升类(XFBoost)算法详解与代码实例
开发语言·人工智能·python·算法·大模型训练·控制算法
外收内放1 天前
Python基础语法练习题(75)
开发语言·python·学习