使用静态构造函数在C#中创建单例

我一直在看c#中创建静态构造函数的文章:

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

现在,他没有提到的一个选项是使用一个简单的静态构造函数。 做以下事情有什么问题吗? 如果它工作,它似乎比他复杂的解决方案恕我直言。

public static class ServiceFactory { static ServiceFactory() { container = new Foo(); } static Foo container; public static Instance { get { return container; } } } 

我问的原因是我正在进行代码审查,并希望保持原样,如果没问题的话。

您的代码没有构建单例。 它正在创建一个Foo的实例,并且可能其他任何人都可以 – 这意味着它不是单身人士。

您已经创建了一个由ServiceFactory的静态变量引用的单个实例,但这不是一回事。

除非你有一些你已经限制的课程,以便只有一个实例,你就没有单身。 你可能有工厂模式,缓存等等 – 但你没有单身人士。

现在你得到的就是这个:

 static Foo container = new Foo(); static ServiceFactory() { } 

…而且我不确定为什么你认为你的版本比上面的更简单。 如果你确实想要实际创建一个单例,那么你将需要一个私有构造函数来处理你想要变成单例的任何类。 那时候,你基本上得到了我的第四个例子,所以我再也不确定你认为你在哪里做事更简单。

当然,您可能根本不需要静态构造函数 – 这取决于您需要多长时间的精确度。 (阅读我在beforefieldinit上的beforefieldinit了解更多详情,以及关于CLR v4更改的博客文章 。)

你的代码等同于他的第四个例子†,除了你使用一个显式的类构造函数,而他是在声明点初始化。

你应该(在大多数情况下)避免使用单例模式,因为它很难扩展和unit testing应用程序。

†除了在使用类构造函数时构造单例时存在行为差异 。

当天的问题是:你想要懒惰的实例化吗? 如果您不需要延迟实例化并且在进行实例化时完全没问题,请随意使用您拥有的范例,或者甚至使用这个稍微冗长的版本:

 public static class ServiceFactory { private static readonly container = new Foo(); public static Instance { get { return container; } } } 

两者都很好,并且完全有效 – 只要你不需要懒惰。 如果你需要懒惰,请使用文章中指出的第五版。