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 有额外性能开销,但单例创建次数极少,影响可以忽略
  • 单例主要解决全局唯一对象管理问题,不应该所有类都使用
相关推荐
Freak嵌入式18 分钟前
RP2040 PIO 编程模型与状态机原理:从硬件架构到工作逻辑全解析
java·大数据·开发语言·单片机·嵌入式硬件·硬件架构
Java小白笔记40 分钟前
Java中大数据实时归集与指标汇总方案
java·大数据·开发语言
随遇而安zx41 分钟前
【地基篇】---Java 8 JVM 知识大纲
java·开发语言·jvm
软件黑马王子1 小时前
4.单例模式问题2:重复挂载
开发语言·单例模式·c#
quantdash_cc1 小时前
批量请求和循环请求有什么区别?从 API 请求次数看量化数据获取的工程设计
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
qq_406981031 小时前
大白话rust系列01注释
开发语言·rust
橘子编程1 小时前
Java邮件发送全攻略:从入门到实战
java·开发语言·spring boot·spring·spring cloud·maven
Tizzy JJ1 小时前
Python + pytest 接口自动化测试框架实战:从零搭建企业级项目骨架
开发语言·python·pytest
海兰1 小时前
【 Python 量化交易】第8章:量化工具箱
开发语言·python