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# SqlHelper应用开发学习

    C# SqlHelper应用开发学习攻略 1. 学习SqlHelper类 SqlHelper是C#中常用的操作数据库的工具类。学习SqlHelper需要掌握以下几个方面: SqlHelper的基本用法,包括连接数据库、执行SQL语句等; SqlHelper的扩展方法,包括重载的ExecuteNonQuery、ExecuteScalar等; SqlHelper…

    C# 2023年6月2日
    00
  • .NET 6 从0到1使用Docker部署至Linux环境超详细教程

    .NET 6 从0到1使用Docker部署至Linux环境超详细教程 本教程将介绍如何使用Docker将.NET 6应用程序部署到Linux环境中。以下是完整的攻略步骤。 步骤 步骤1:创建.NET 6 Web API项目 首先,需要创建一个.NET 6 Web API项目。可以使用以下命令在命令行中创建一个新的.NET 6 Web API项目: dotne…

    C# 2023年5月17日
    00
  • C#实现简单的登录界面

    C#实现简单的登录界面攻略 总览 对于一个拥有用户注册和登录功能的网站而言,登录界面是不可或缺的。C#是一种广泛使用的编程语言,使得创建登录界面并实现各种用户验证变得相对容易。本篇攻略将向你展示如何使用C#实现一个简单的登录界面。 步骤 步骤一:创建项目 首先,我们需要创建一个新的C#项目。在Visual Studio中,选择“文件” -> “新建” …

    C# 2023年6月6日
    00
  • .net实现ping的实例代码

    首先,我们需要了解一下什么是ping,以及它在网络中的作用。 Ping是什么? 在网络中,我们可以使用Ping命令来测试网络连通性。Ping命令可以向另一台计算机发送一个数据包,然后等待该计算机返回响应。如果该计算机能够正常响应,表示网络连通正常;如果该计算机未响应,则表示网络可能存在问题。 在.NET中,我们可以使用System.Net.NetworkIn…

    C# 2023年5月31日
    00
  • C#使用Enum.TryParse()实现枚举安全转换

    当我们需要将字符串或整数等类型转换为枚举类型时,可以使用C#提供的Enum.TryParse()方法来实现安全转换,避免了在转换时可能会抛出异常的情况。 什么是枚举类型 枚举类型是一种特殊的值类型(Value Type),它限定了该类型变量只能是预先定义好的枚举值中的一种。枚举类型可以在程序中用于表示特定的常量值,例如星期几、性别等。 Enum.TryPar…

    C# 2023年5月14日
    00
  • C#实现在线点餐系统

    C#实现在线点餐系统需要包含以下步骤: 1. 确定需求和功能 在开发任何系统之前,我们必须确定系统需要完成的功能。在在线点餐系统中,一般需要实现以下功能: 用户可以注册或登录,推荐使用ASP.NET Identity框架来实现用户认证和授权功能 用户可以在系统中浏览菜单、查看菜品详细信息、添加菜品到购物车并下单 店家可以登录系统查看订单信息,更新订单状态等功…

    C# 2023年6月1日
    00
  • 基于asp.net实现图片在线上传并在线裁剪功能

    下面是基于asp.net实现图片在线上传并在线裁剪功能的完整攻略: 1. 确定上传插件 为了实现在线上传图片,我们需要选择一个合适的上传插件。目前市场上比较流行的上传插件有uploadify和plupload,我们可以根据需求自行选择。 在这里,我以uploadify为例进行说明。 2. 实现图片上传 需先引入jquery、uploadify相关的js和cs…

    C# 2023年5月31日
    00
  • C#中尾递归的使用、优化及编译器优化

    C#中尾递归的使用、优化及编译器优化 什么是尾递归 尾递归是一种特殊的递归,即递归调用在递归函数的最后一条语句中进行。尾递归的优点是可以优化成迭代形式,避免堆栈溢出的问题。在一些函数式编程语言中,尾递归的优化是由编译器自动完成的,而在C#中,我们需要手动进行优化,否则C#编译器并不会自动进行优化。 C#中尾递归的使用 要使用尾递归,首先需要确保递归调用在递归…

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