public sealed class Singleton
{
static readonly Singleton instance=new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
我认为即使从readonly
成员实例中删除instance
关键字,单例仍然可以正常工作。
请帮助我纠正我对这里概念的理解。
答案 0 :(得分:11)
因为如果字段没有标记为只读,则可以在Singleton类中进行修改。当然,它仍然无法被外部世界修改,但如果在程序的生命周期中存在多个实例,则单例实际上不是单例,并且只读说明符强制执行您想要的语义单身人士课程。
编辑回应:
- 它的静态,只存在一个实例。
- 价值无法改变,因为它没有设定者。
醇>
静态变量当然可以设置为在运行时引用不同的对象。如果仅在类中由于它是私有的,则值可以改变。如果实施该类以使该字段仅被分配一次,则在实践中不会成为问题。但是,由于假定的意图是单例实例永远不会改变,readonly修饰符保证构造函数之外的那些语义。它不是必需,因为类的客户端不能更改引用,但它是首选的,因为它a)使代码的意图清晰,b)防止引用即使在类中也被更改。
答案 1 :(得分:7)
在这种情况下,使用readonly
并不重要,但它通过指示字段的性质来强制执行代码的语义。就个人而言,我总是将readonly
关键字用于所有字段声明,其值仅初始化一次。它还可以帮助编译器在某些情况下执行某些优化。
答案 2 :(得分:0)
我不认为readonly必须出现在这里 - 它只对延迟初始化有意义。如果静态字段标记为只读 - 它只能在声明或静态构造函数中初始化。如果实例未标记为只读 - 您可以在首次调用Instance属性时初始化它。
顺便说一下,我认为使用带有双重检查锁定功能的单例更好:
public sealed class Singleton
{
private Singleton()
{
// Initialize here
}
private static volatile Singleton _singletonInstance;
private static readonly Object syncRoot = new Object();
public static Singleton Instance
{
get
{
if(_singletonInstance == null)
{
lock(syncRoot))
{
if(_singletonInstance == null)
{
_singletonInstance = new Singleton();
}
}
}
return _singletonInstance;
}
}
}
答案 3 :(得分:0)
我在课堂上删除了readonly,因为我想创建一个 OneAtaTimeleton (而不是一个Singleton)。
为什么呢?好吧,该类包含一些配置,我希望用户(管理员)能够在应用程序运行时进行更改。所以,我在类中添加了一个静态Reload()方法,该方法有:
instance = new Configuration();
因此需要删除readonly。
构造函数的私有版本加载配置(通过非静态方法)。