什么是C#中的单例?

非常简单的问题。

什么是Singleton,我应该什么时候使用它?

单例是一个只允许创build自己的一个实例的类,并且可以简单,方便地访问该实例。 单身的前提是跨软件开发的模式。

有一个C#实现“在C#中实现单例模式”,涵盖了大部分你需要知道的东西 – 包括一些关于线程安全的好build议。

说实话,你需要实现一个singleton是非常罕见的 – 在我看来,它应该是你应该知道的事情之一,即使它不被太频繁地使用。

它是什么:在应用程序的整个生命周期中只有一个持久实例的类。 请参阅单例模式 。

当你应该使用它:尽可能less。 只有当你确定你需要它的时候。 我不愿意说“从来没有”,但通常有更好的select,如dependency injection或简单的静态类。

你要求C#。 微不足道的例子:

 public class Singleton { private Singleton() { // Prevent outside instantiation } private static readonly Singleton _singleton = new Singleton(); public static Singleton GetSingleton() { return _singleton; } } 

另一种在c#中实现单例的方法,我个人更喜欢这种方式,因为你可以作为属性而不是方法访问​​singeton类的实例。

 public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton Instance { get { if (instance == null) instance = new Singleton(); return instance; } } //instance methods } 

但是,据我所知,这两种方式都被认为是“正确的”,所以这只是个人风格。

一个Singleton(而不是绑定到C#,这是一个面向对象的devise模式)就是当你希望在整个应用程序中只允许创build一个类的实例。 用途通常包括全球资源,尽pipe从个人经验来看,他们往往是巨大的痛苦来源。

虽然只能有一个单例的实例,但它与静态类不一样。 一个静态类只能包含静态方法,永远不能实例化,而单例实例可以像其他任何对象一样使用。

 using System; using System.Collections.Generic; class MainApp { static void Main() { LoadBalancer oldbalancer = null; for (int i = 0; i < 15; i++) { LoadBalancer balancerNew = LoadBalancer.GetLoadBalancer(); if (oldbalancer == balancerNew && oldbalancer != null) { Console.WriteLine("{0} SameInstance {1}", oldbalancer.Server, balancerNew.Server); } oldbalancer = balancerNew; } Console.ReadKey(); } } class LoadBalancer { private static LoadBalancer _instance; private List<string> _servers = new List<string>(); private Random _random = new Random(); private static object syncLock = new object(); private LoadBalancer() { _servers.Add("ServerI"); _servers.Add("ServerII"); _servers.Add("ServerIII"); _servers.Add("ServerIV"); _servers.Add("ServerV"); } public static LoadBalancer GetLoadBalancer() { if (_instance == null) { lock (syncLock) { if (_instance == null) { _instance = new LoadBalancer(); } } } return _instance; } public string Server { get { int r = _random.Next(_servers.Count); return _servers[r].ToString(); } } } 

我从dofactory.com那里得到了代码,没有什么特别的 ,但是我发现这比使用Foo和Bar的例子 更好 , 这个例子是关于C#3.0 Design Patterns的Judith Bishop的。

如果你看代码,我们实际上是在for循环上创build新的对象,所以创build新的对象,但重用实例,因此旧的平衡器和新的平衡器具有相同的实例。 由于在函数GetLoadBalancer()上使用了静态关键字,尽pipe具有不同的服务器值(它是随机列表), GetLoadBalancer()上的静态属于types本身,而不属于特定对象。

此外还有双重检查locking在这里

 if (_instance == null) { lock (syncLock) { if (_instance == null) 

因为从MSDN

lock关键字确保一个线程不会进入关键代码段,而另一个线程处于关键段。 如果另一个线程试图input一个locking的代码,它将等待,阻止,直到对象被释放。

所以每次都会发出互斥锁,即使不需要,也是不必要的,所以我们有空的检查。

希望它有助于清理更多。

如果我的理解是错误的,请评论。

以下是单身人士: http : //en.wikipedia.org/wiki/Singleton_pattern

我不知道C#,但是它在所有语言中都是一样的,只是实现有所不同。

一般情况下,你应该避免单身人士,但在某些情况下,这是非常方便的。

对不起我的英语不好 ;)

这是一个devise模式,它不是特定于C#。 更多关于它在互联网上,所以就像这个维基百科文章 。

在软件工程中,单例模式是一种devise模式,用于限制一个类的实例化到一个对象。 当需要恰好一个对象来协调系统中的操作时,这非常有用。 这个概念有时候被推广到当只有一个对象存在时更有效地操作的系统,或者将实例化限制到一定数量的对象(比如五个)。 有些人认为这是一种反模式,认为它被过度使用,在实际上并不需要某个类的唯一实例的情况下引入不必要的限制,并将全局状态引入到应用程序中。

你应该使用它,如果你想要一个只能被实例化一次的类。

我用它来查找数据。 从DB加载一次。

 public sealed class APILookup { private static readonly APILookup _instance = new APILookup(); private Dictionary<string, int> _lookup; private APILookup() { try { _lookup = Utility.GetLookup(); } catch { } } static APILookup() { } public static APILookup Instance { get { return _instance; } } public Dictionary<string, int> GetLookup() { return _lookup; } } 

什么是单身人士:
它是一个只允许创build自己的一个实例的类,通常可以简单地访问该实例。

何时应该使用:
这取决于实际情况。

注意:请不要使用db连接,具体的答案请参考 @Chad Grant的答案

如何实现:

 public sealed class Singleton { private static readonly Singleton instance = new Singleton(); // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit static Singleton() { } private Singleton() { } public static Singleton Instance { get { return instance; } } } 

你也可以通过Lazy<T>实现单例

请参考

Singleton类用于为整个应用程序域创build单个实例。

 public class Singleton { private static Singleton singletonInstance = CreateSingleton(); private Singleton() { } private static Singleton CreateSingleton() { if (singletonInstance == null) { singletonInstance = new Singleton(); } return singletonInstance; } public static Singleton Instance { get { return singletonInstance; } } } 

这篇文章中,我们描述了如何使用只读variables创build线程安全单例类以及它们在应用程序中的实际使用。

单例是一种远程对象,用于服务多个客户端。 这些对象保持状态而不是singel调用对象types