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技术站