安阳博客:[C#.NET 拾遗补漏]06:单例模式最佳实践

admin/2020-07-30/ 分类:科技/阅读:

人人好,这是【C#.NET 拾遗补漏】专辑的第 06 篇文章。今天讲讲人人熟悉的单例模式。

单例模式大概是所有设计模式中最简朴的一种,若是在面试时被问及熟悉哪些设计模式,你可能第一个答的就是单例模式。

单例模式的实现分为两种:饿汉式懒汉式。前者是在静态组织函数执行时就立刻实例化,后者是在程序执行过程中第一次需要时再实例化。两者有各自适用的场景,实现方式也都很简朴,唯一在设计时要思量的一个问题就是:实例化时需要保证线程平安。

饿汉式

饿汉式实现很简朴,在静态组织函数中立刻举行实例化:

public class Singleton { private static readonly Singleton _instance; static Singleton() { _instance = new Singleton(); } public static Singleton Instance { get { return _instance; } } } 

注重,为了确保单例性,需要使用 readonly 关键字声明实例不能被修改。

以上写法可简写为:

public class Singleton { private static readonly Singleton _instance = new Singleton(); public static Singleton Instance { get { return _instance; } } } 

这里的 new Singleton() 等同于在静态组织函数中实例化。在 C# 7 中还可以进一步简写如下:

public class Singleton { public static Singleton Instance { get; } = new Singleton(); } 

一句代码就搞定了,此写法,实例化也是在默认的静态组织函数中举行的。若是是饿汉式需求,这种实现是最简朴的。有人会问这会不会有线程平安问题,若是多个线程同时挪用 Singleton.Instance 会不会实例化了多个实例。不会,由于 CLR 确保了所有静态组织函数都是线程平安的

注重,不能这么写:

public class Singleton { public static Singleton Instance => new Singleton(); } // 等同于: public class Singleton { public static Singleton Instance { get { return new Singleton(); } } } 

这样会导致每次挪用都市建立一个新实例。

懒汉式

懒汉式单例实现需要思量线程平安问题,先来看一段经典的线程平安的单列模式实现代码:

public sealed class Singleton { private static volatile Singleton _instance; private static readonly object _lockObject = new Object(); public static Singleton Instance { get { if (_instance == null) { lock (_lockObject) { if (_instance == null) { _instance = new Singleton(); } } } return _instance; } } } 

网上搜索 C# 单例模式,大部分都是这种使用 lock 来确保线程平安的写法,这是经典尺度的单例模式的写法,没问题,很放心。在 lock 里外都做一次 instance 空判断,双保险,足以保证线程平安和单例性。但这种写法似乎太麻烦了,而且容易写错。早在 C# 3.5 的时刻,就有了更好的写法,使用 Lazy<T>

示例代码:

public class LazySingleton { private static readonly Lazy<LazySingleton> _instance = new Lazy<LazySingleton>(() => new LazySingleton()); public static LazySingleton Instance { get { return _instance.Value; } } } 

挪用示例:

public class Program { public static void Main() { var instance = LazySingleton.Instance; } } 

使用 Lazy<T> 可以使工具的实例化延迟到第一次被挪用的时刻执行,通过接见它的 Value 属性来建立并获取实例,而且读取一个 Lazy<T> 实例的 Value 属性只会执行一次实例化代码,确保了线程平安。

祝,编码愉快!

,

Allbet手机版下载

欢迎进入Allbet手机版下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

TAG:
阅读:
广告 330*360
广告 330*360

热门文章

HOT NEWS
  • 周榜
  • 月榜
Sunbet_进入申博sunbet官网
微信二维码扫一扫
关注微信公众号
新闻自媒体 Copyright © 2002-2019 Sunbet 版权所有
二维码
意见反馈 二维码