C#Singleton with public';实例';字段而不是属性
本文关键字:属性 字段 with C#Singleton 实例 public | 更新日期: 2023-09-27 18:28:40
考虑带有类型初始化的单例模式的"标准"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() { }
}
这对我来说似乎很好,但我只见过最上面的一个,所以我想知道我是否错过了什么。
静态属性有意义吗?
是的。它隐藏了从完全相同的类中的字段检索值的实现细节。如果您公开了该字段,那么您将永远使用该实现(假设您以后无法更改/重新生成所有引用它的代码)。如果你使用一处房产,你可以稍后使用:
- 更改为使用
Lazy<T>
- 如果您希望类中有其他静态方法,请使用嵌套类中的字段来获得可能更延迟的初始化
- 使用一些尚待设计的新颖方案
基本上,有了一处房产,你就有了未来改变的选择。有了田地,你就没有了。
我过去并不认为这是一个相关的区别,但在Noda Time中,我遇到过复杂的类型初始化排序问题,这使得我能够控制这类事情变得非常重要。我在早期版本中公开了一个公共静态只读字段,后来我后悔了:(
公共静态只读字段的工作原理是仍然是一个单例——它只会给你更少的控制。
顺便说一句,可能希望在类中添加一个空的静态构造函数。有关更多详细信息,请参阅我关于singleton实现和beforefieldinit
的文章。
在Singleton模式的情况下,拥有一个公共只读字段而不仅仅是一个getter并不是很有害。
"标准"实现使用getter的原因是与其他公共getter保持一致,并使您在getter比poublic字段更合适的所有其他情况下养成良好的习惯(例如,在不更改接口的情况下添加功能)
Readonly意味着它是一个无法写入的实例变量,static是一个可以在不实例化对象的情况下读取的变量。例如,您可以这样称呼它们:
//Readonly
var readonlySingleton = new singleton();
var result = readnlySingleton.Instance;
//static readonly
var result = singleton.Instance;