C#问题中的单例模式

log*_*eks 1 c# singleton

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

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

   private Singleton(){}

   public static Singleton Instance
   {
      get 
      {
         return instance; 
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

因为Singleton实例由私有静态成员变量引用,所以实例化不会发生,直到对Instance属性的调用首次引用该类.因此,此解决方案实现了lazy instantiation属性的一种形式,如Singleton的Design Patterns形式.

我不太确定何时会将内存分配给

private static readonly Singleton instance 
Run Code Online (Sandbox Code Playgroud)

1)在调用Instance属性时甚至在它之前它会发生吗?

2)我需要强制类创建一个新的内存,有时清除其内容.这样做是否安全set

set
{
instance = null;
}
Run Code Online (Sandbox Code Playgroud)

Vla*_*lad 7

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

您可以在Jon Skeet的文章"在C#中实现单例模式"中找到更多见解,请参阅方法4.

基本上,为了实现真正的懒惰行为之类的东西

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

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

    public static Singleton Instance
    {
        get { return instance; }
    }
}
Run Code Online (Sandbox Code Playgroud)

足够.

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

编辑
实际上,正如上面提到的文章所示,由于BeforeFiledInit标记,不保证在第一次访问时创建实例.你需要添加一个空的静态构造函数,这样它保证是懒惰的.否则,将在程序启动和首次访问之间的某个未指定时间创建实例.(已知.NET运行时2.0拥有更加热切的策略,因此您可能无法获得惰性行为.)

引用上述文章:

类型初始值设定项的懒惰仅在类型未标记为特殊标志时由.NET保证beforefieldinit.不幸的是,C#编译器[...]标记了所有没有静态构造函数的类型beforefieldinit.

编辑2
如果要清理单例对象,则应将此功能包含在类Singleton本身中.

删除属性值将有效地使您的类不再是单例!想象一下,有人访问单例并获取单例实例.之后,您将属性设置为null.Singleton该类的现有对象不会消失,因为它仍然有一个参考!因此,下次访问该Instance属性时,Singleton将创建该类的另一个实例.所以你丢失了两件事:你的对象不再是单例(因为你同时存在2个实例),并且内存也没有被清除.


Sam*_*eff 7

当加载类本身时,单例实例将被加载到内存中,这时可以调用它的方法开始执行.调用该类的实际行不必实际执行.这是一个非常小的区别,但是当静态构造函数或静态字段初始化程序可以抛出错误(这里没有)时,可能会产生难以调试的问题.

这在使用新Lazy<T>实现的.NET 4中得到修复.

http://msmvps.com/blogs/jon_skeet/archive/2010/01/26/type-in​​itialization-changes-in-net-4-0.aspx

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
} 
Run Code Online (Sandbox Code Playgroud)

http://csharpindepth.com/Articles/General/Singleton.aspx