【问题标题】:Using Static constructors to create a singleton in C#在 C# 中使用静态构造函数创建单例
【发布时间】:2010-10-14 21:31:30
【问题描述】:

我一直在这里查看有关在 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;
    }
  }
}

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

【问题讨论】:

    标签: c# static singleton


    【解决方案1】:

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

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

    除非您有某个类被限制为只能有一个实例,否则您没有单例。你可能有工厂模式、缓存等等——但你没有单例。

    现在你得到的就是这个:

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

    ...我不确定为什么你认为你的版本比上面的更简单。如果您确实想实际创建一个单例,那么无论您想将其变成单例的什么类,您都需要一个私有构造函数。到那时,你基本上已经有了我的第四个例子,所以我再次不确定你认为你在哪里让事情变得更简单。

    当然,您可能根本不需要静态构造函数——这取决于您需要的时间有多精确。 (阅读my article on beforefieldinit了解更多详情,以及我的blog post about the CLR v4 changes。)

    【讨论】:

    • 不确定我是否可以将构造函数设为私有 - 有问题的对象是 Castle Windsor IOC 容器。但建议采纳。干杯!
    【解决方案2】:

    您的代码等同于他的第四个示例†,只是您使用的是显式类构造函数,而他在声明点进行初始化。

    您应该(在大多数情况下)避免使用单例模式,因为它很难扩展和对应用程序进行单元测试。

    †​​ 除非有a behavioural difference 关于在使用类构造函数时何时构造单例。

    【讨论】:

    • 单例,取决于实现,是相当可测试的。如果有的话,单例方式比一堆静态方法更容易测试。
    • @Randolpho:我谈论的是单例模式,而不是一般的单例实例。我不是建议使用静态方法(尽管如果纯函数它们是无害的)。
    • @Paul Ruane:具有讽刺意味的是,我觉得单例模式失败的时间最长——直到我对单元测试很感兴趣,此时我发现我更愿意使用经过良好测试的 Singleton,而不是静态方法。
    • @Randolpho:那么如何在测试之间重置有状态的单例模式实例,以便一个测试不会干扰下一个测试?
    • 根据您引用的那篇行为差异文章,使用我们上面的静态构造函数是一种更好的方法 - 我正确吗?
    【解决方案3】:

    今天的问题是:你是否想要惰性实例化?如果您不需要惰性实例化并且完全可以使用加载实例化,请随意使用您拥有的范例,或者甚至使用这个不太冗长的版本:

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

    两者都可以正常工作并且完全有效——只要您不需要懒惰。如果你需要偷懒,使用文章中指出的第五个版本。

    【讨论】:

    • 我认为他的代码很懒,因为静态构造函数仅在第一次使用该类时才被调用。
    • 但我认为我所拥有的懒惰的,因为我认为静态构造函数仅在第一次访问类时才被调用?
    • @Chris:是的,你所拥有的是懒惰的。它只是不是一个单例。
    猜你喜欢
    • 2011-04-19
    • 2015-08-06
    • 2014-01-10
    • 2010-11-11
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    • 2014-08-25
    • 2011-05-08
    相关资源
    最近更新 更多