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日

相关文章

  • C#使用TcpListener及TcpClient开发一个简单的Chat工具实例

    C#使用TcpListener及TcpClient开发一个简单的Chat工具实例是一个比较常见的网络编程应用场景。下面我将提供一个完整的攻略,指导如何实现该工具。 1. 需求分析 首先,我们需要明确Chat工具的需求。我们需要基于TCP协议实现一个聊天工具,并保持服务器端和客户端之间的连接。服务器需要接收客户端的消息,并将消息广播给所有连接。客户端需要能够连…

    C# 2023年6月1日
    00
  • C#通过oledb访问access数据库的方法

    C#通过oledb访问access数据库的完整攻略 简介 在C#中,我们可以使用OLE DB提供程序来访问基于 OLE DB 的数据库。Microsoft Access是OLE DB的支持者之一,因此我们可以使用OLE DB连接器来访问Microsoft Access数据库。这篇攻略将向您介绍如何通过OLE DB访问Access数据库。 步骤 以下是访问Ac…

    C# 2023年6月2日
    00
  • C#实现网络小程序的步骤详解

    下面是详细讲解“C#实现网络小程序的步骤详解”的完整攻略。 1. 确定需求和功能 在开始任何项目之前,我们必须明确需求和目标。首先,确定你的网络小程序需要完成的功能,包括功能模块、界面设计等,以此为基础,设计项目结构和流程。 2. 确定开发环境 C#可以在Windows平台上运行,因此您需要安装Visual Studio等适用的软件开发工具。您需要安装.NE…

    C# 2023年6月1日
    00
  • C#使用NPOI导入Excel的方法详解

    下面详细讲解“C#使用NPOI导入Excel的方法详解”的完整攻略。 安装NPOI 要使用NPOI,需要先安装它。可以通过NuGet包管理器搜索和安装NPOI。 导入Excel的方法 首先,需要先读取Excel文件。可以使用NPOI中的HSSFWorkbook或XSSFWorkbook类来打开Excel文件。 using NPOI.HSSF.UserMode…

    C# 2023年6月7日
    00
  • 一次.net core异步线程设置超时时间的实战记录

    一次.NET Core异步线程设置超时时间的实战记录 在.NET Core应用程序中,异步线程是非常常见的。但是,如果异步线程执行时间过长,可能会导致应用程序性能下降。为了避免这种情况,我们可以设置异步线程的超时时间。在本攻略中,我们将介绍如何在.NET Core应用程序中设置异步线程的超时时间。 步骤一:创建.NET Core应用程序 首先,需要创建一个.…

    C# 2023年5月17日
    00
  • c#中token的使用方法实例

    针对“c#中token的使用方法实例”,我可以提供以下攻略: 理解Token 在c#中,Token是一种数字签名,常用于验证数据的完整性和真实性。它是一种访问令牌,用于验证用户的身份和权限。通过Token,服务器可以验证用户的请求是否合法,并且可以防止一些常见的安全问题,如跨站脚本、CSRF等攻击。 Token的生成 Token的生成通常包括以下步骤: 密钥…

    C# 2023年5月31日
    00
  • Unity 实现鼠标滑过UI时触发动画的操作

    Unity 实现鼠标滑过UI时触发动画的操作可以按照以下步骤: 第一步 创建UI对象和动画 首先需要创建一个UI对象,比如一个按钮,并且在它上面创建需要触发的动画。可以通过Animator组件来创建动画效果,或者直接在RectTransform组件上的Position/Scale等属性上进行动画操作。 第二步 创建鼠标滑过事件 接下来需要给这个UI对象创建一…

    C# 2023年6月3日
    00
  • C#中的正则表达式双引号问题

    C#中的正则表达式中双引号问题,主要是因为C#语言本身使用双引号来定义字符串,而正则表达式中也常常需要使用双引号来定义某些模式。因此,在将正则表达式作为字符串处理时,需要注意双引号字符的转义问题。 1. 双引号的转义 在C#中,要在字符串中插入双引号字符,需要使用反斜杠(\)字符进行转义,例如: string str = "This is a \&…

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