C#实现单例模式的6种方法小结

C#实现单例模式的6种方法小结

什么是单例模式?

单例模式是一种软件设计模式,它限制了某个类只能有一个实例,并且该实例可以从全局访问。单例模式通常用于控制资源的共享,并且可以避免竞态条件(race condition)。

单例模式的优点

  • 单例模式可以保证某个类在全局范围内只有一个对象实例,这可以减少系统中的内存占用和资源消耗
  • 单例模式可以确保某些操作只会被执行一次,这可以在程序创建和销毁对象的时候提供更加灵活的控制
  • 单例模式可以增强代码的可维护性和可扩展性,并使代码更容易实现测试驱动开发

C#实现单例模式的6种方法

方法1:使用静态变量

在C#中,可以使用静态变量来实现单例模式。静态变量只会被初始化一次,因此我们可以在类里面声明一个静态变量,并将其初始化为类的实例。每次使用该类时,我们可以直接访问这个静态变量,从而拿到唯一的实例。

public class Singleton1
{
    private static Singleton1 instance = new Singleton1();

    private Singleton1() {}

    public static Singleton1 Instance
    {
        get { return instance; }
    }
}

方法2:使用静态构造函数

在C#中,每个类都有一个静态构造函数(static constructor),它在创建类实例之前自动调用。我们可以在静态构造函数里面初始化一个静态变量,这样就可以保证类只有一个实例。

public class Singleton2
{
    private static Singleton2 instance;

    private Singleton2() {}

    static Singleton2()
    {
        instance = new Singleton2();
    }

    public static Singleton2 Instance
    {
        get { return instance; }
    }
}

方法3:使用双重检查锁定

在使用方法1和方法2实现单例模式的时候,我们需要使用锁来保证线程安全。但是由于锁的开销比较大,因此我们可以使用双重检查锁定(double-checked locking)来减少锁的使用次数,提高性能。

public class Singleton3
{
    private static Singleton3 instance;
    private static readonly object syncRoot = new object();

    private Singleton3() {}

    public static Singleton3 Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new Singleton3();
                    }
                }
            }

            return instance;
        }
    }
}

方法4:使用延迟初始化

在C#中,可以使用延迟初始化(lazy initialization)来实现单例模式。延迟初始化可以推迟对象的创建,直到第一次访问对象时才创建,从而避免资源的浪费。

public class Singleton4
{
    private static readonly Lazy<Singleton4> lazyInstance = new Lazy<Singleton4>(() => new Singleton4());

    private Singleton4() {}

    public static Singleton4 Instance
    {
        get { return lazyInstance.Value; }
    }
}

方法5:使用属性

在C#中,可以使用属性(property)来实现单例模式。属性可以在读取和写入时执行特定的代码,因此我们可以在属性的get访问器中返回唯一的类实例。

public class Singleton5
{
    private static readonly Singleton5 instance = new Singleton5();

    private Singleton5() {}

    public static Singleton5 Instance
    {
        get { return instance; }
    }
}

方法6:使用容器

在C#中,可以使用容器(container)来实现单例模式。容器可以存储对象的实例,并在需要的时候返回该实例,从而确保全局范围内只有一个对象实例。

public class Singleton6
{
    private static readonly Lazy<Singleton6> lazyInstance = new Lazy<Singleton6>(() => new Singleton6());

    private Singleton6() {}

    public static Singleton6 Instance
    {
        get { return lazyInstance.Value; }
    }
}

public class SingletonContainer
{
    private readonly Dictionary<string, object> container = new Dictionary<string, object>();

    public T GetInstance<T>() where T : class
    {
        var typeName = typeof(T).FullName;
        if (!container.ContainsKey(typeName))
        {
            container[typeName] = Activator.CreateInstance(typeof(T));
        }

        return container[typeName] as T;
    }
}

以上6种方法都可以实现单例模式,每种方法都有其优缺点。我们可以根据具体的场景选择合适的方法来实现单例模式。

示例1:使用静态变量实现单例模式

以下是一个使用静态变量实现单例模式的示例代码:

class Program
{
    static void Main(string[] args)
    {
        var instance1 = Singleton1.Instance;
        var instance2 = Singleton1.Instance;
        Console.WriteLine(instance1.GetHashCode());
        Console.WriteLine(instance2.GetHashCode());
        Console.ReadLine();
    }
}

public class Singleton1
{
    private static Singleton1 instance = new Singleton1();

    private Singleton1() {}

    public static Singleton1 Instance
    {
        get { return instance; }
    }
}

输出结果:

31133577
31133577

可以看出,两个实例的哈希码是相同的,说明它们是同一个对象。

示例2:使用容器实现单例模式

以下是一个使用容器实现单例模式的示例代码:

class Program
{
    static void Main(string[] args)
    {
        var container = new SingletonContainer();

        var instance1 = container.GetInstance<Singleton6>();
        var instance2 = container.GetInstance<Singleton6>();

        Console.WriteLine(instance1.GetHashCode());
        Console.WriteLine(instance2.GetHashCode());
        Console.ReadLine();
    }
}

public class Singleton6
{
    private static readonly Lazy<Singleton6> lazyInstance = new Lazy<Singleton6>(() => new Singleton6());

    private Singleton6() {}

    public static Singleton6 Instance
    {
        get { return lazyInstance.Value; }
    }
}

public class SingletonContainer
{
    private readonly Dictionary<string, object> container = new Dictionary<string, object>();

    public T GetInstance<T>() where T : class
    {
        var typeName = typeof(T).FullName;
        if (!container.ContainsKey(typeName))
        {
            container[typeName] = Activator.CreateInstance(typeof(T));
        }

        return container[typeName] as T;
    }
}

输出结果:

31284847
31284847

可以看出,两个实例的哈希码是相同的,说明它们是同一个对象。

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

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • C#基本概念列举详解

    C#基本概念列举详解 什么是C#? C#是由微软公司开发和维护的一种现代编程语言。C#最初发布于2000年,旨在成为Windows桌面应用程序开发领域的首选语言。C#是一种跨平台语言,可在Windows、Linux和Mac OS等各种操作系统上运行。C#具有很多现代编程语言的特性,例如自动内存管理、强类型、泛型和LINQ查询。 C#的主要特性 C#包含许多高…

    C# 2023年6月1日
    00
  • .Net Core 集成 Kafka的步骤

    在本攻略中,我们将详细讲解如何在.Net Core中集成Kafka,并提供两个示例说明。 安装Kafka:首先,我们需要安装Kafka。我们可以从官方网站下载Kafka,并按照官方文档进行安装和配置。 安装Confluent.Kafka:接下来,我们需要安装Confluent.Kafka NuGet包。我们可以使用Visual Studio的NuGet包管理…

    C# 2023年5月16日
    00
  • 用上这几种.NET EF Core性能调优,查询性能飙升

    1、避免在循环中进行查询操作: 避免在循环中进行查询操作,可以将查询结果缓存到内存中,然后对内存中的数据进行操作,可以提高性能。这种方式适合集合数据量少的数据,否则利大于弊。 // 不建议的方式:在循环中进行查询操作 foreach (var item in itemList) { var result = context.Items.FirstOrDefa…

    C# 2023年4月18日
    00
  • C# DataTable.Select()根据条件筛选数据问题

    针对“C# DataTable.Select()根据条件筛选数据问题”,我为你准备了以下完整攻略: 什么是C# DataTable? C# DataTable是一种内存中的表格类型,它通常用于在程序中操作和存储数据。DataTable类提供了一系列方法,可以实现增、删、改、查等常用操作。 什么是DataTable.Select()方法? C# DataTab…

    C# 2023年5月15日
    00
  • C# 运用params修饰符来实现变长参数传递的方法

    来详细讲解一下“C# 运用params修饰符来实现变长参数传递的方法”的完整攻略。 什么是params修饰符 在C#中,params是一个修饰符,用于指示方法的参数可以接受任意数量的参数。这意味着,您可以使用一个方法来接受一个或多个参数并将其传递给该方法。 如何使用params修饰符 下面是一个简单的示例,说明如何使用params修饰符: public vo…

    C# 2023年6月7日
    00
  • asp.net 光棒效应实现代码

    ASP.NET 光棒效应(Nyan Cat Progress Bar)是一种在页面加载或异步请求时,使用CSS3动画实现的进度条。在本文中,我们将深入了解如何通过 ASP.NET 实现这种可爱的进度条效果。 实现步骤 第一步:创建结构 HTML中应该包括进度条的容器和过渡滑块,如下代码所示: <div> <div class="p…

    C# 2023年5月31日
    00
  • c#中task与thread的区别及使用讲解

    C#中Task与Thread的区别及使用讲解 在 C# 中,Task 和 Thread 是比较常用的多线程编程方式。Task 是从 .NET Framework 4.0 开始引入的新特性,主要用于异步编程;而 Thread 则是比较传统的多线程编程方式。 区别 1. 创建方式和语法 Task 的创建可以使用 Task 类、Task.Factory 或 asy…

    C# 2023年6月1日
    00
  • .NET Core API之格式化输出对象OutputFormatter

    下面是详细的“.NET Core API之格式化输出对象OutputFormatter”的攻略。 1. OutputFormatter是什么? OutputFormatter是ASP.NET Core MVC框架中的一个组件,用于将响应数据对象序列化为HTTP响应内容。ASP.NET Core MVC框架中提供了多种不同格式的OutputFormatter,…

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