c#单例模式(Singleton)的6种实现

单例模式(Singleton)

单例模式是一种创建型设计模式,它保证一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在需要确保有且仅有一个对象被创建时,使用单例模式就是最佳选择。

实现单例模式的六种方法

1. 饿汉式(饿汉式单例模式是线程安全的,极其简单)

饿汉式单例模式是指,在类加载的时候就创建一个对象实例,并且永久驻留在内存中,以供后续使用。

public sealed class Singleton
{
    private static readonly Singleton _instance = new Singleton();

    private Singleton() { }

    public static Singleton Instance
    {
        get { return _instance; }
    }
}

2. 懒汉式(懒汉式单例模式在多线程环境下存在问题)

懒汉式单例模式是指,在第一次使用时才创建对象实例。如果多个线程同时调用GetInstance()方法,可能会导致创建多个实例的问题,因此需要进行线程同步,保证只创建一个实例。

public sealed class Singleton
{
    private static Singleton _instance = null;
    private static readonly object padlock = new object();

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (padlock)
                {
                    if (_instance == null)
                    {
                        _instance = new Singleton();
                    }
                }
            }
            return _instance;
        }
    }
}

3. Double Check Locking(双重检查锁定)

Double Check Locking模式是一种优化的懒汉式单例模式,确保在多线程环境下只会创建一个对象实例。

public sealed class Singleton
{
    private static volatile Singleton _instance;
    private static readonly object padlock = new object();

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (padlock)
                {
                    if (_instance == null)
                    {
                        _instance = new Singleton();
                    }
                }
            }
            return _instance;
        }
    }
}

4. 静态内部类

静态内部类单例模式是指,在访问静态内部类的静态字段Instance时,会创建唯一的实例。

public sealed class Singleton
{
    private Singleton() { }

    private static class SingletonHolder
    {
        internal static readonly Singleton INSTANCE = new Singleton();
    }

    public static Singleton Instance
    {
        get { return SingletonHolder.INSTANCE; }
    }
}

5. 枚举

枚举单例模式是指,使用枚举类型创建单例对象,枚举类型是在Java 5中引入的。

public enum Singleton
{
    INSTANCE;

    // method
    public void showMessage()
    {
        Console.WriteLine("Hello World!");
    }
}

调用:

Singleton.INSTANCE.showMessage();

6. 单元素的枚举类型

单元素的枚举类型单例模式是指,在枚举中使用一个实例来实现单例。

public sealed class Singleton
{
    internal enum SingletonEnum
    {
        INSTANCE
    }

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            return SingletonEnum.INSTANCE.GetInstance();
        }
    }

    internal Singleton GetInstance()
    {
        return SingletonEnum.INSTANCE;
    }
}

示例说明

以下是一个示例,展示如何使用饿汉式单例模式实现一个日志系统。用文本文档文件存储日志信息。

public sealed class Logger
{
    private static readonly Logger _instance = new Logger();

    private Logger() { }

    public static Logger Instance
    {
        get { return _instance; }
    }

    public void Log(string message)
    {
        using (StreamWriter writer = new StreamWriter("log.txt", true))
        {
            writer.WriteLine(DateTime.Now.ToString() + ": " + message);
        }
    }

    public void Clear()
    {
        File.Delete("log.txt");
    }
}

我们可以在整个系统中调用Log()方法,如下所示:

Logger.Instance.Log("Hello World!");

此时,将在项目根目录下创建一个log.txt文件,并向其中写入“Hello World!”和当前时间。

另一个示例:以下是一个示例,展示如何使用枚举单例模式实现一个配置管理器。用键值对存储配置信息。

public enum ConfigurationManager
{
    INSTANCE;

    private Dictionary<string, string> configData = new Dictionary<string, string>();

    public void SetConfigValue(string key, string value)
    {
        configData[key] = value;
    }

    public string GetConfigValue(string key)
    {
        string value;
        configData.TryGetValue(key, out value);
        return value;
    }
}

我们可以使用以下方法将配置值写入配置管理器:

ConfigurationManager.INSTANCE.SetConfigValue("Url", "https://www.example.com");

并使用以下方法获取配置值:

string url = ConfigurationManager.INSTANCE.GetConfigValue("Url");

总结

以上是六种常见的单例模式实现方法。根据实际应用场景的不同,可以选择不同的实现方法。对于绝大多数应用场景来说,饿汉式单例模式是最好的选择,它既简单又高效,并且能够保证线程安全。

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

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

相关文章

  • C#字符串String及字符Char的相关方法

    下面就是关于 C# 字符串 String 及字符 Char 相关方法的详细攻略。 字符串 String 字符串简介 C# 中的字符串是一组字符的集合,用双引号引起来的字符序列,在 C# 中被认为是值类型。字符串可以包含任何字符,包括特殊字符、数字和字母。 C# 字符串是不可改变的,也就是说,一旦创建了一个字符串对象,就不可以改变它。 字符串的方法 C# 的 …

    C# 2023年5月15日
    00
  • c# 使用Entity Framework操作Access数据库的示例

    下面是详细讲解“c#使用EntityFramework操作Access数据库的示例”的完整攻略: 一、概述 在使用C#编程时,我们常常需要对数据库进行操作。其中较为常见的数据库有MySQL、SQL Server等。而今天我们要介绍的是如何使用EntityFramework操作Access数据库。 EntityFramework是.NET Framework中…

    C# 2023年5月15日
    00
  • .NET Core 环境变量详解

    一、概述 软件从开发到正式上线,在这个过程中我们会分为多个阶段,通常会有开发、测试、以及上线等。每个阶段对应的环境参数配置我们会使用不同的参数。比如数据库的连接字符串,开发环境一般我们都是连接的测试库。以前这种情况通常是 COPY 两个同名的配置文件来进行处理,然后在本地就使用本地的配置,生产环境就使用生产环境的配置文件,十分麻烦。而 ASP .NET CO…

    C# 2023年4月25日
    00
  • c#使用windows服务更新站点地图的详细示例

    下面是“c#使用windows服务更新站点地图的详细示例”的完整攻略,本文将由以下几部分组成:需求分析、技术选型、开发流程和实现示例。 需求分析 我们需求是实现一个使用 Windows 服务来自动更新网站地图(SiteMap)的功能。这个服务需要能够自动遍历网站,根据业务逻辑生成站点地图,并更新网站。在此基础上,我们可以选择以特定的时间间隔来调度这个服务。 …

    C# 2023年5月31日
    00
  • Go中的gRPC入门教程详解

    Go中的gRPC入门教程详解 什么是gRPC? gRPC是一种高性能、通用的开源框架,用于构建分布式系统。它由Google公司推出,基于Protocol Buffers(一种高效的序列化技术)开发,支持多种语言(如Go、Java、Python等)。gRPC主要解决了分布式系统中服务间通信的问题,极大地简化了开发人员的工作量。 基本概念 在了解gRPC的使用之…

    C# 2023年6月3日
    00
  • C#中间语言及ILDASM工具用法

    C#编译器会将C#源代码编译成一个叫做CIL(Common Intermediate Language,公用中间语言)的中间语言,这个中间语言是基于栈的虚拟机语言。CIL是一种基于栈的虚拟机语言,每个CIL指令都会入栈一个或多个值,并且返回结果也会通过栈来返回。 ILDASM是一个IL(Intermediate Language,中间语言)反汇编器,允许用户…

    C# 2023年6月3日
    00
  • C#线程同步的几种方法总结

    下面我将为大家详细介绍一下“C#线程同步的几种方法总结”的攻略。 标题一:什么是线程同步 在多线程编程中,不同线程可能会访问共享资源,如果没有进行合理的同步控制,可能会导致数据不一致等问题。因此,在多线程编程中,必须采用合适的同步机制,保证线程间的正确协作和数据的一致性。 标题二:C#线程同步的几种方法 C#提供了多种线程同步的方法,下面我们将逐一介绍。 1…

    C# 2023年5月15日
    00
  • C#中for循环、while循环循环执行的方法

    C#中的for循环和while循环是常用的循环结构,用于重复执行相同或类似的代码块,下面是它们的详细讲解和示例说明: for循环 for循环是一种经典的循环语句,用于重复执行一段代码,可以控制循环变量的初始值、终止条件和每次循环变量的增量。for循环的语法如下: for (初始化表达式; 循环条件; 迭代语句) { // 循环体语句 } 其中,初始化表达式只…

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