C#Singleton with public' Instance'字段而不是属性

时间:2013-08-23 08:00:44

标签: c# singleton

考虑具有类型初始化的单例模式的“标准”C#实现:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }

    private Singleton() { }
}

静态属性中有什么意义吗?如果静态字段被标记为只读,那么肯定无法从任何地方写入,包括从类外部。对于更简洁的实现,这会有效吗?:

public sealed class Singleton
{
    public static readonly Singleton Instance = new Singleton();
    private Singleton() { }
}

对我来说似乎很好,但我只看过最常用的,所以我想知道我错过了什么错误。

3 个答案:

答案 0 :(得分:7)

  

静态属性中有什么意义吗?

是。它隐藏实现细节,从完全相同的类中的字段中检索值。如果您公开该字段,那么您将永远坚持该实现(假设您以后无法更改/重建引用它的所有代码)。如果你使用一个属性,你可以稍后:

  • 更改为使用Lazy<T>
  • 如果要在类中使用其他静态方法,请使用嵌套类中的字段来获得可能更加懒惰的初始化
  • 使用一些尚未设计的新的时髦方案

基本上,通过财产,您可以选择未来的变化。有了一个领域,你没有。

我曾经不认为这是一个相关的区别,但在Noda Time中,我遇到过复杂类型初始化排序问题使我能控制这类事情非常重要的情况。我在早期版本中暴露了一个公共静态只读字段,后来我后悔了:(

公共静态只读字段的工作方式仍然是单例 - 它只是减少了控制权。

顺便说一下,你可能希望在你的类中添加一个空的静态构造函数。有关详细信息,请参阅singleton implementationsbeforefieldinit上的文章。

答案 1 :(得分:1)

对于Singleton模式,拥有公共只读字段而不仅仅是getter并不是非常有害。

“标准”实现使用getter的原因是为了与其他公共getter保持一致,并让你对所有其他getter更适合poublic字段的情况采取良好习惯(用于添加功能例如改变界面)

答案 2 :(得分:-2)

Readonly意味着它是一个无法写入的实例变量,static是一个可以在不实例化对象的情况下读取的变量。例如,您可以按如下方式调用它们:

//Readonly
var readonlySingleton = new singleton();
var result = readnlySingleton.Instance;

//static readonly
var result = singleton.Instance;