Singleton缩短了实施时间

Ada*_*sko 5 c#

我总是看到像这样实施的单身人士:

public class Singleton
{
    static Singleton instance;
    static object obj = new object();

    public static Singleton Instance
    {
        get
        {
            lock (obj)
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }

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

像这样实现它是否有问题:

public class Singleton
{
    static readonly Singleton instance = new Singleton();
    public static Singleton Instance
    {
        get { return instance; }
    }

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

?它在第一次实现的同一时刻被初始化,所以我想知道为什么这不是一个流行的解决方案?它应该也更快,因为不需要条件,锁定并且字段被标记为只读,这将使编译器进行一些优化

我们不要谈论单身(反)模式本身

Cod*_*ter 7

CLR 将在首次使用该字段(或任何其他静态)字段时初始化该字段.它承诺以线程安全的方式这样做.

您的代码之间的区别在于第一位代码支持线程安全的延迟初始化,而第二位则不支持.这意味着当您的代码永远不会访问Singleton.Instance第一个代码时,new Singleton()将永远不会创建任何代码.对于第二类,只要您访问Instance 或(直接或间接)该类的任何其他静态成员,它就会.甚至更糟 - 它可能在此之前被初始化,因为你缺少一个静态构造函数.

支持更短,更易读的代码,因为.NET 4可以Lazy<T>用来显着缩短第一个代码块:

public class Singleton
{
    static readonly Lazy<Singleton> instance = 
        new Lazy<Singleton>(() => new Singleton());

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

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

由于Lazy<T>承诺线程安全.这将确保new Singleton()仅被调用一次,并且仅在Singleton.Instance实际使用时.