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日

相关文章

  • .net实现webservice简单实例分享

    关于“.NET实现WebService简单实例分享”的攻略,我将按照以下格式为您进行详细讲解: 1. 什么是Web Service? Web Service是指通过网络对外提供的一组应用程序接口,具有跨平台性、松耦合等特点。通过Web Service,开发人员可以将自己的应用程序接口(API)发布到Internet上,以使得全世界的人都能发现并使用自己的AP…

    C# 2023年5月31日
    00
  • asp.net使用DataSet的ReadXml读取XML文件及Stream流的方法

    下面是详细讲解“asp.net使用DataSet的ReadXml读取XML文件及Stream流的方法”的完整攻略。 使用DataSet的ReadXml读取XML文件 准备工作 首先,你需要创建一个XML文件并填充它。例如,下面是一个名为books.xml的简单XML文件。 <books> <book> <title>A S…

    C# 2023年5月31日
    00
  • C#11新特性使用案例详解

    C#11新特性使用案例详解 C#语言在11版的时候增加了一些新特性,这些新特性可以让我们在编写代码时更加方便,提高代码的可读性和性能。接下来我们来详细讲解一下这些新特性的使用案例。 新特性列表 以下是C#11中新增加的新特性: 针对null的操作符 ?, ?? 和 ?. 元组的方法和参数 局部函数的放宽限制 外来机构的类定义 用括号来括起不支持的字面表达式类…

    C# 2023年5月14日
    00
  • C#连接mariadb(MYSQL分支)代码示例分享

    下面我将为您详细讲解“C#连接mariadb(MYSQL分支)代码示例分享”的完整攻略。 一、准备工作 在连接 mariadb 前需要先安装 mariadb 的 C# 驱动,如下所示: PM> Install-Package MySql.Data 二、连接 mariadb 数据库 通过以下代码示例,我们可以使用 C# 连接 mariadb 数据库: s…

    C# 2023年6月2日
    00
  • C# TabControl控件中TabPage选项卡切换时的触发事件问题

    C#的TabControl控件中,TabPage选项卡的切换可以由用户手动点击或者程序动态切换两种方式触发,对应的事件就是TabControl的SelectedIndexChanged事件。下面将详细讲解如何在C#中处理TabControl控件中TabPage选项卡切换的问题。 监听TabControl的SelectedIndexChanged事件 当用户手…

    C# 2023年5月15日
    00
  • 关于C# if语句中并列条件的执行

    关于C#中if语句中并列条件的执行,可以分为以下三种情况: 如果是使用&&符号连接的两个条件,则第一个条件返回false时,整个if语句直接返回false,不会判断第二个条件。只有当第一个条件返回true时,才会判断第二个条件,如果第二个条件也返回true,整个if语句才会返回true。具体示例代码如下: int a = 1, b = 2, …

    C# 2023年5月15日
    00
  • C# Winform实现复制文件显示进度

    实现文件复制进度显示的方法有很多,比如使用进度条控件来实时更新复制进度,或者使用后台线程来监控文件复制状态等。 下面是C# Winform实现复制文件显示进度的完整攻略: 1.创建Winform应用程序 首先,我们需要创建一个Winform应用程序作为我们的开发环境。打开Visual Studio,选择新建项目,选择“Windows Forms应用程序”,输…

    C# 2023年6月7日
    00
  • asp.net UpdaeProgress的简单用法

    下面是 “ASP.NET UpdateProgress的简单用法”的完整攻略: 什么是ASP.NET UpdateProgress? ASP.NET UpdateProgress 允许在触发异步操作时显示进度指示器。 我们可以使用 UpdatePanel 控件或自己的自定义异步回发来合并 UpdateProgress 控件。 如何实现ASP.NET Upda…

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