C#问题中的单例模式

C#问题中的单例模式,c#,singleton,C#,Singleton,我在研究C的单例模式,我从msdn网站上找到了这个例子 public sealed class Singleton { private static readonly Singleton instance = new Singleton(); private Singleton(){} public static Singleton Instance { get { return instance; }

我在研究C的单例模式,我从msdn网站上找到了这个例子

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

   private Singleton(){}

   public static Singleton Instance
   {
      get 
      {
         return instance; 
      }
   }
}
因为Singleton实例是 由私有静态成员引用 变量,则实例化不会 直到类第一次出现 由对实例的调用引用 财产。因此,这个解决方案 实现了一种懒惰的 实例化属性,如 设计模式是单例的一种形式

我不太确定什么时候会分配内存给你

private static readonly Singleton instance 
1) 它会在调用实例属性时发生还是在调用之前发生

2) 有时我需要强制类创建新内存以清除其内容。使用
set
这样做安全吗

set
{
instance = null;
}

在您提供的示例代码中,将在首次访问该类时创建singleton实例。这意味着您的示例在第一次调用
Instance

在Jon Skeet的文章中可以找到更多的见解,请参见方法4

基本上,为了实现真正的懒惰行为

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

    static Singleton(){}
    private Singleton(){}

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

(但无论如何,在上述文章中可以找到完整且更好的概述。)

编辑
实际上,正如前面提到的文章所述,由于BeforeFiledInit标记,实例不保证在第一次访问时创建。您需要添加一个空的静态构造函数,这样可以保证它是惰性的。否则,将在程序启动和首次访问之间的某个未指定时间创建实例。(众所周知,.NET runtime 2.0具有更积极的策略,因此您可能不会出现懒惰行为。)

引述上述文章:

只有当类型没有使用名为beforefieldinit的特殊标志标记时,.NET才能保证类型初始值设定项的惰性。不幸的是,C#编译器[…]将所有没有静态构造函数的类型[…]标记为
beforefieldinit

编辑2
如果希望清理singleton对象,则应将此功能包含到类
singleton
本身中


删除属性值将有效地使您的类不再是单一的!假设有人访问singleton并获得singleton实例。然后将属性设置为
null
Singleton
类的现有对象不会消失,因为仍然有对它的引用!因此,下次访问
实例
属性时,将创建
单例
类的另一个实例。因此,您丢失了两件事:您的对象不再是单一实例(因为您同时存在两个实例),并且内存也没有被清除。

在您提供的示例代码中,单一实例将在首次访问该类时创建。这意味着您的示例在第一次调用
Instance

在Jon Skeet的文章中可以找到更多的见解,请参见方法4

基本上,为了实现真正的懒惰行为

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

    static Singleton(){}
    private Singleton(){}

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

(但无论如何,在上述文章中可以找到完整且更好的概述。)

编辑
实际上,正如前面提到的文章所述,由于BeforeFiledInit标记,实例不保证在第一次访问时创建。您需要添加一个空的静态构造函数,这样可以保证它是惰性的。否则,将在程序启动和首次访问之间的某个未指定时间创建实例。(众所周知,.NET runtime 2.0具有更积极的策略,因此您可能不会出现懒惰行为。)

引述上述文章:

只有当类型没有使用名为beforefieldinit的特殊标志标记时,.NET才能保证类型初始值设定项的惰性。不幸的是,C#编译器[…]将所有没有静态构造函数的类型[…]标记为
beforefieldinit

编辑2
如果希望清理singleton对象,则应将此功能包含到类
singleton
本身中


删除属性值将有效地使您的类不再是单一的!假设有人访问singleton并获得singleton实例。然后将属性设置为
null
Singleton
类的现有对象不会消失,因为仍然有对它的引用!因此,下次访问
实例
属性时,将创建
单例
类的另一个实例。因此,您丢失了两件事:您的对象不再是单例对象(因为您同时存在两个实例),并且内存也没有被清除。

您发布的引用中说:

实例化直到 该类首先由 调用实例属性


所以。。。无论何时调用
.Instance
,或之前的某个时候。

它在您发布的引用中说:

实例化直到 该类首先由 调用实例属性


所以。。。无论何时调用
.Instance
,或之前的某个时间点。

在第一次访问静态成员之前,以及在调用静态构造函数之前(如果有)初始化静态成员


在首次访问静态成员之前,以及在调用静态构造函数(如果有)之前,初始化静态成员

C#规范规定:

10.5.5.1静态字段初始化

类的静态字段变量初始值设定项对应于按文本顺序执行的赋值序列,在类声明中以文本顺序出现。如果一个静态公司