【问题标题】:Singleton class design in C#, are these two classes equivalent?C#中的单例类设计,这两个类是等价的吗?
【发布时间】:2010-04-12 07:28:50
【问题描述】:

我在 this great resource 上阅读 C# 中的单例类设计,并决定使用替代方案 4:

public sealed class Singleton1
{
    static readonly Singleton1 _instance = new Singleton1();

    static Singleton1()
    {
    }

    Singleton1()
    {
    }

    public static Singleton1 Instance
    {
        get
        {
            return _instance;
        }
    }
}

现在我想知道这是否可以使用这样的自动属性重写?

public sealed class Singleton2
{
    static Singleton2()
    {
        Instance = new Singleton2();
    }

    Singleton2()
    {
    }

    public static Singleton2 Instance { get; private set; }
}

如果只是为了可读性,我肯定更喜欢第二个版本,但我想把它做好。

【问题讨论】:

  • 编译2个版本,用Reflector反编译看看区别

标签: c# design-patterns refactoring singleton


【解决方案1】:

它可以正常工作,但实际上并不相同。

即使属性被标记为私有,它也不是只读的(例如,只能在构造函数中赋值)。因此你应该使用第一个变体,它表达了一个变量(引用)在初始赋值后不会改变的意图。

【讨论】:

    【解决方案2】:

    这不等效,因为自动属性的支持字段不会是 readonly

    【讨论】:

      【解决方案3】:

      属性的支持字段不是readonly,但由于这是一个私有属性,所以问题不是很大。但是第一个实现的最大优势是您可以删除静态构造函数,但对于第二个实现,您使用静态构造函数。静态构造函数可以增加性能损失(请参阅http://msdn.microsoft.com/en-us/library/ms182275(v=VS.100).aspx

      【讨论】:

      • 性能损失来自被标记为“beforefieldinit”的类,这是线程安全所必需的。关于单例的文章提到了这一点。
      【解决方案4】:

      这里要考虑的另一件事是,初始化属性比初始化字段要多。

      Singleton2 中的静态构造函数调用属性的 set 方法,然后设置支持字段的值。我不知道这是否或如何影响线程安全,但这是另一个区别。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-24
        • 1970-01-01
        相关资源
        最近更新 更多