C#中单例模式写法
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#中单例模式写法,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3239字,纯文字阅读大概需要5分钟。
内容图文
![C#中单例模式写法](/upload/InfoBanner/zyjiaocheng/772/9a8018c56036436196f1a431b6f9eaa2.jpg)
在C#中,我们对于只会生成一个实例的类对其实现单例模式。
首先我们实现的是适用于单线程环境的单例模式。要注意我们必须将构造函数设为私有,防止其它类创建实例,代码如下:
using System;
namespace ConsoleApp1
{
public sealed class Singleton
{
private Singleton()
{
}
private static Singleton _instance = null;
public static Singleton Instance
{
get
{
if(_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
class Program
{
static void Main(string[] args)
{
}
}
}
只有当_instance为null的时候我们才会创建一个实例来避免重复创建,但是这种写法在单线程的时候工作正常,多线程时就会出现问题。加入我们有两个线程分别想要同时运行判断instance是否为null,并且instance在这个时刻确实为null,那么两个线程就都会创建一个实例,因此我们需要在程序中加上一个同步锁,代码如下:
using System;
namespace ConsoleApp1
{
public sealed class Singleton
{
private Singleton()
{
}
private static readonly object syncObj = new object();
private static Singleton _instance = null;
public static Singleton Instance
{
get
{
lock(syncObj)
{
if (_instance == null)
{
_instance = new Singleton();
}
}
return _instance;
}
}
}
class Program
{
static void Main(string[] args)
{
}
}
}
当我们使用这种写法创建实例时就能够避免当两个线程同时创建实例时的问题。因为当想要创建实例的时候,只有一个线程得到了同步锁,另一个线程等待。第一个线程完成后,同步锁释放,并且单例创建完成,第二个线程获得锁之后不会再去创建单例,而是直接使用第一个线程锁创建的单例,这样就解决了多线程所带来的问题。
而这种写法导致的问题是效率低下,因为加锁是一个耗时的操作,而这种写法在每一次获取单例的时候都会进行加锁,这是应该避免的。这一改进很简单,我们只要将加锁的步骤放到判断instance为null的时候就行了,代码如下:
using System;
namespace ConsoleApp1
{
public sealed class Singleton
{
private Singleton()
{
}
private static readonly object syncObj = new object();
private static Singleton _instance = null;
public static Singleton Instance
{
get
{
if (_instance == null)
{
lock (syncObj)
{
if(_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
}
class Program
{
static void Main(string[] args)
{
}
}
}
但是这种加锁的写法有点复杂,容易出问题,这时我们可以考虑使用C#中的静态构造函数,保证构造函数仅调用一次,写法如下:
using System;
namespace ConsoleApp1
{
public sealed class Singleton
{
private Singleton()
{
}
private static Singleton _instance = new Singleton();
public static Singleton Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
class Program
{
static void Main(string[] args)
{
}
}
}
我们在初始化static变量_instance的时候创建实例,而因为变量为static,会在调用static构造函数之前执行构造,因此保证仅调用一次。但是这一段代码的问题是,如果我们在该类中存在一个static函数或其他static变量,如果我们使用到了那些static内容而非static的_instance,那么这个_isntance就会过早的创建,进而降低效率。
我们使用了一种嵌套类来解决这一问题:
using System;
namespace ConsoleApp1
{
public sealed class Singleton
{
private Singleton()
{
}
public static Singleton Instance
{
get
{
return Nested._instance;
}
}
private class Nested
{
static Nested()
{
}
internal static readonly Singleton _instance = new Singleton();
}
}
class Program
{
static void Main(string[] args)
{
}
}
}
我们在内部定义了私有类型Nested,当第一次获取单例的时候,我们会去获得Nested内部的_instance,而要想获取就会调用Nested的静态构造函数。由于Nested为私有类,我们仅仅会在这里有唯一的一次调用,这样就防止了提前构造的发生。
内容总结
以上是互联网集市为您收集整理的C#中单例模式写法全部内容,希望文章能够帮你解决C#中单例模式写法所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。