一般的单身人士

对于一般的单身人士,你们对此有何看法?

using System; using System.Reflection; // Use like this /* public class Highlander : Singleton { private Highlander() { Console.WriteLine("There can be only one..."); } } */ public class Singleton where T : class { private static T instance; private static object initLock = new object(); public static T GetInstance() { if (instance == null) { CreateInstance(); } return instance; } private static void CreateInstance() { lock (initLock) { if (instance == null) { Type t = typeof(T); // Ensure there are no public constructors... ConstructorInfo[] ctors = t.GetConstructors(); if (ctors.Length > 0) { throw new InvalidOperationException(String.Format("{0} has at least one accesible ctor making it impossible to enforce singleton behaviour", t.Name)); } // Create an instance via the private constructor instance = (T)Activator.CreateInstance(t, true); } } } } 

创建单例类只是几行代码,并且由于难以制作通用单例,我总是编写这些代码行。

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

 private static Singleton _instance = new Singleton(); 

line删除了锁定的需要,因为静态构造函数是线程安全的。

好吧,它不是真正的单身 – 因为你无法控制T ,你可以拥有尽可能多的T实例。

(删除了线程;记录了双重检查的用法)

我删除了我之前的答案,因为我没有注意到检查非公共构造函数的代码。 但是,这是一个仅在执行时执行的检查 – 没有编译时检查,这是对它的攻击。 它还依赖于有足够的访问权来调用非公共构造函数,这增加了一些限制。

此外,它不禁止内部构造函数 – 因此您最终可能会使用非单例。

我个人在静态构造函数中创建实例,以实现简单的线程安全性。

基本上我不是一个粉丝 – 创建单例类很容易,而且你不应该经常这样做。 单身人士是测试,脱钩等的痛苦。

这是我使用.NET 4的观点

 public class Singleton where T : class, new() { Singleton (){} private static readonly Lazy instance = new Lazy(()=> new T()); public static T Instance { get { return instance.Value; } } } 

它正在使用如下:

  public class Adaptor { public static Adaptor Instance { get { return Singleton.Instance;}} } 

合并AndreasN的答案和Jon Skeet的“ 第四版 – 不太懒,但不使用锁的线程安全 ”的Singleton c#实现,为什么不使用代码片段来完成所有的艰苦工作:

   
Singleton Class TWSoft Generates a singleton class Expansion Singleton singleton
ClassName Replace with class name MySingletonClass

然后您可以将其保存到.snippt文件中,并将其添加到VS IDE(Tools-> Code Snippets Manager)

通用单件工厂存在问题,因为它是通用的,您不控制实例化的singleton类型,因此您永远不能保证您创建的实例将是应用程序中的唯一实例。

因此, 您无法创建通用的单件工厂 – 它会破坏模式本身。

我不认为使用generics对单身人士有用。 因为您总是可以创建多个实例,因此根据定义它不是单例。 如果你需要一个懒惰的单身人士并要求它成为一个真正的单身人士一个简单的解决方案(基于亚历山大的例子)

 public sealed class Adaptor { private static readonly Lazy instance = new Lazy(() => new Adaptor()); public static Adaptor Instance { get { return instance.Value; } } private Adaptor() { } } 

您无法将此正确地重构为单独的通用单例。

另见: http : //csharpindepth.com/Articles/General/Singleton.aspx