C#实现单例模式的多种方式

C#实现单例模式的多种方式

单例模式是设计模式中的一种,指的是创建一个类的实例后,该类只允许创建一个实例,并且提供一个访问该实例的全局访问点。在很多场景下,单例模式被广泛使用,比如线程池、缓存、配置文件等等。

在C#中实现单例模式的方式比较多,下面就介绍一些常见的实现方式,分别是:懒汉式、饿汉式、静态构造器、枚举实现、双重锁定以及 .NET 4.0+ 中新增的 Lazy 实现。

1. 懒汉式

懒汉式是指在调用获取实例的方法时才实例化对象,即只有当需要使用实例时才会去创建,因此称之为“懒汉式”。

这种方式比较简单,代码如下:

public sealed class Singleton
{
    private static Singleton instance = null;
    private Singleton() { }
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}

在上面的代码中,我们在访问 Instance 属性时,会先检查 instance 是否为 null,如果是,则创建一个新的 Singleton 实例,否则直接返回单例对象。

需要注意的是,这种方式并不是线程安全的,会存在多线程同时调用 Instance 属性时会创建多个实例的问题。

2. 饿汉式

相比懒汉式,饿汉式是指在程序启动时就创建好单例对象,因此称之为“饿汉式”。

这种方式比较简单,代码如下:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();
    private Singleton() { }
    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

在上面的代码中,instance 被声明为 readonly,确保在多线程访问时不会被修改,因此是线程安全的。

3. 静态构造器

静态构造器是指在第一次使用类之前,.NET框架会自动调用静态构造函数来执行一些初始化操作,因此我们可以在静态构造函数中创建单例对象,示例代码如下:

public sealed class Singleton
{
    private static readonly Singleton instance = null;
    static Singleton()
    {
        instance = new Singleton();
    }
    private Singleton() { }
    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

如上代码,静态构造器会在第一次访问 Singleton 类之前被执行,因此可以在其中执行一些初始化操作,比如创建单例对象。

需要注意的是,如果单例类的静态构造函数中抛出了异常,那么 instance 将不会被赋值,因此使用时需要特别小心。

4. 枚举实现

在 .NET 2.0 之后,C#对枚举类型进行了扩展,可以将枚举类型看做是一种特殊的单例模式实现方式。

示例代码如下:

public enum Singleton
{
    Instance
}

在上面的代码中,我们把 Singleton 定义为一个枚举类型,其只有一个成员 Instance。当我们需要访问单例对象时,只需要使用 Singleton.Instance 即可获得。

需要注意的是,枚举类型的实现方式比较巧妙,但是其存在一些限制,比如无法继承和延迟初始化等。

5. 双重锁定

双重锁定是指在判断实例是否为 null 时,使用了两个锁来确保线程安全,因此称之为“双重锁定”。

示例代码如下:

public sealed class Singleton
{
    private static readonly object syncObj = new object();
    private static Singleton instance = null;
    private Singleton() { }
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncObj)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
}

在上面的代码中,我们使用了两个锁 syncObjinstance,并使用了两次 if 语句进行判断。

需要注意的是,双重锁定的实现方式比较复杂,而且可能存在一些细微的问题,比如CPU指令重排等问题。

6. Lazy实现

在 .NET 4.0 以及更高版本中,C#新增了一个 Lazy<T> 类型,可以方便地实现延迟初始化及线程安全,示例代码如下:

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazyInstance = new Lazy<Singleton>(() => new Singleton());
    private Singleton() { }
    public static Singleton Instance
    {
        get
        {
            return lazyInstance.Value;
        }
    }
}

在上面的代码中,我们通过 Lazy<Singleton> 类型实现了单例对象的延迟初始化和线程安全,在调用 Instance 属性时才实例化对象,并且能够确保在多线程访问时只会创建一个实例。

需要注意的是,Lazy<T> 是一种非常优秀的实现方式,不仅易于使用,而且性能也比较高,需要尽量推荐使用。

总结

本文介绍了 C# 实现单例模式的多种方式,分别是懒汉式、饿汉式、静态构造器、枚举实现、双重锁定以及 .NET 4.0+ 中新增的 Lazy 实现。各种实现方式都有其优缺点,需要根据实际需求和应用场景进行选择。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#实现单例模式的多种方式 - Python技术站

(0)
上一篇 2023年6月6日
下一篇 2023年6月6日

相关文章

  • Unity实现单机游戏每日签到系统

    下面我将详细讲解“Unity实现单机游戏每日签到系统”的完整攻略。本文将分为以下三个部分来进行讲解: 准备工作 实现过程 示例说明 准备工作 在开始实现签到系统之前,您需要准备以下工作: Unity开发环境:Unity是一款跨平台的游戏引擎,您需要提前安装好Unity并且熟悉Unity的基础操作。 程序代码:签到系统的核心是代码实现,您需要根据自己的游戏需求…

    C# 2023年6月1日
    00
  • Python SQLite3数据库操作类分享

    Python SQLite3数据库操作类分享 Python中操作SQLite数据库是一项重要的技能,在这里分享一种Python SQLite3数据库操作类的实现方法,方便大家在使用SQLite数据库时更加便捷。 SQLite3数据库介绍 SQLite是一个嵌入式的关系型数据库管理系统,特点是不需要独立的数据库服务器进程或操作系统,而是像其他应用程序库一样,以…

    C# 2023年6月3日
    00
  • C#实现异步编程的方法

    C#实现异步编程的方式有很多种,我们分别来讲解一下。 1. 使用async/await关键字 async/await是C#5.0版本中引入的一种异步编程方式,它可以将异步代码的编写和使用变得非常简单。使用async/await,可以将异步操作的结果异步返回给调用方,并且不会阻塞调用线程。 示例1 public async Task<int> Ta…

    C# 2023年6月6日
    00
  • .NET Core开源 DDD微服务 支持 多租户 单点登录 多级缓存、自动任务、分布式、日志、授权和鉴权 、网关 、注册与发现 系统架构 docker部署

    源代码地址https://github.com/junkai-li/NetCoreKevin基于NET6搭建跨平台DDD思想WebApi架构、IDS4单点登录、多缓存、自动任务、分布式、多租户、日志、授权和鉴权、CAP、SignalR、 docker部署  如需简约项目可直接去除项目引用 解耦设计都可以单独引用 架构默认全部引用并启动 项目启动时注意相关 R…

    C# 2023年4月27日
    00
  • 如何将Winform移植到.NET Core 3.0

    将Winform移植到.NET Core 3.0的完整攻略如下: 确认.NET Core 3.0 SDK已安装 在开始移植之前,需要确认已安装.NET Core 3.0 SDK。您可以在命令行中运行以下命令来检查是否已安装.NET Core 3.0 SDK: dotnet –version 如果输出的版本号为3.0或更高版本,则.NET Core 3.0 …

    C# 2023年5月16日
    00
  • ASP.NET(C#)实现一次性动态上传多张图片的代码(多个文件)

    以下是实现 ASP.NET(C#)一次性动态上传多张图片的代码攻略。 1. 创建HTML表单 在HTML中创建一个包含多个文件的上传表单,可参考以下代码: <form id="form1" runat="server" enctype="multipart/form-data"> &lt…

    C# 2023年5月31日
    00
  • 认识ASP.NET配置文件Web.config

    ASP.NET配置文件Web.config是ASP.NET应用程序的核心文件,用于配置应用程序的行为和设置,在ASP.NET应用程序的开发和部署过程中,了解和操作Web.config文件是必不可少的。下面是认识ASP.NET配置文件Web.config的完整攻略: 1. Web.config文件的作用 Web.config文件是ASP.NET应用程序最常用的…

    C# 2023年5月31日
    00
  • C#开发Winform实现学生管理系统

    C#开发Winform实现学生管理系统 目录 准备工作 创建新项目 创建数据库 绘制界面 编写代码 示例说明1:添加学生信息 示例说明2:查询学生信息 准备工作 在开始开发学生管理系统之前,我们需要先准备好以下工具: Visual Studio 2019:用于编写C#程序 SQL Server 2019:用于创建和管理数据库 SQL Server Manag…

    C# 2023年5月31日
    00
合作推广
合作推广
分享本页
返回顶部