简体   繁体   English

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

[英]Using Static constructors to create a singleton in C#

I've been looking at the article on creating static constructors in c# here: 我一直在看c#中创建静态构造函数的文章:

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

Now, one option he doesn't mention is using a simple static constructor. 现在,他没有提到的一个选项是使用一个简单的静态构造函数。 Is there any issue with doing something like the below? 做下面这样的事情有什么问题吗? If it works, it seems simpler than his complicated solutions IMHO. 如果它工作,它似乎比他复杂的解决方案恕我直言。

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

  public static Instance {
    get {
    return container;
    }
  }
}

The reason i ask is i'm doing a code review and want to leave it as-is if it's fine. 我问的原因是我正在进行代码审查,如果没问题,我希望保持原样。

Your code isn't building a singleton. 您的代码没有构建单例。 It's creating an instance of Foo , and presumably anyone else could too - which means it isn't a singleton. 它正在创建一个Foo的实例,并且可能其他任何人都可以 - 这意味着它不是单身人士。

You've created a single instance which is referred to by a static variable in ServiceFactory , but that's not the same thing. 您已经创建了一个由ServiceFactory的静态变量引用的单个实例,但这不是一回事。

Unless you have some class which you've restricted so that there can only ever be one instance of it, you don't have a singleton. 除非你有一些你限制的课程,以便只有一个实例,你就没有单身。 You may have a factory pattern, a cache, whatever - but you don't have a singleton. 你可能有工厂模式,缓存,等等 - 但你没有单身人士。

Now what you've got is equivalent to this: 现在你得到的就是这个:

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

... and I'm not sure why you think your version is simpler than the above. ...而且我不确定为什么你认为你的版本比上面的更简单。 If you do want to actually create a singleton, you're going to need a private constructor for whatever class you're trying to turn into a singleton. 如果你确实想要实际创建一个单例,那么你需要一个私有构造函数用于你想要变成单例的任何类。 At that point, you've basically got my fourth example, so again I'm not sure where you think you're making things simpler. 在那一点上,你基本上得到了我的第四个例子,所以我再也不确定你认为你在哪里做事更简单。

Of course, you may not need a static constructor at all - it depends on how precise you need the timing to be. 当然,您可能根本不需要静态构造函数 - 这取决于您需要多长时间的精确度。 (Read my article on beforefieldinit for more details, along with my blog post about the CLR v4 changes .) (阅读我在beforefieldinit上的beforefieldinit了解更多详情,以及关于CLR v4更改的博客文章 。)

Your code is equivalent to his fourth example†, except you are using an explicit class constructor whereas he is initialising at point of declaration. 你的代码等同于他的第四个例子†,除了你使用的是显式类构造函数,而他是在声明点初始化。

You should (in most cases) shy away from using the singleton pattern, as it makes it very hard to scale and unit-test an application. 你应该(在大多数情况下)避免使用单例模式,因为它很难扩展和单元测试应用程序。

† except there is a behavioural difference as to when the singleton is constructed when class constructors are used. †除了在使用类构造函数时构造单例时存在行为差异

The question of the day is this: do you want lazy instantiation or not? 这一天的问题是:你想要懒惰的实例化吗? If you do not need lazy instantiation and are perfectly fine with on-load instantiation, feel free to use the paradigm you have, or even use this somewhat less verbose version: 如果您不需要延迟实例化并且在进行实例化时完全没问题,请随意使用您拥有的范例,或者甚至使用这个稍微冗长的版本:

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

Both work fine and are perfectly valid -- as long as you don't need lazy. 两者都很好,并且完全有效 - 只要你不需要懒惰。 If you need lazy, use the Fifth version pointed out in the article. 如果你需要懒惰,请使用文章中指出的第五版。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM