【问题标题】:Singleton shortened implementation单例缩短实现
【发布时间】:2015-01-15 10:10:38
【问题描述】:

我总是看到这样实现的单例:

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() { }
}

这样实现有什么问题吗:

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

    protected Singleton() { }
}

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

请不要谈论单例(反)模式本身

【问题讨论】:

  • 您可能有兴趣阅读 Jon Skeet 的 Implementing the Singleton Pattern in C#,向下滚动到“第四版 - 不那么懒惰,但不使用锁是线程安全的”
  • 这是一个品味问题。 Lazy<T> 还有第三种模式。请注意,您的第一个示例还应该在进入锁之前检查无效性。
  • 这样实现没有什么问题(除了你应该将支持字段声明为readonly)。但请注意,它不像第一个版本那样懒惰,因为对象是在调用类中的静态方法时创建的,而不是在访问属性时创建的。

标签: c#


【解决方案1】:

该(或任何其他静态)字段的 CLR will initialize the field upon the first use。它promises to do so in a thread-safe manner

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

更喜欢更短且更易读的代码,因为 .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() { }
}

作为Lazy&lt;T&gt;promises thread-safety。这将确保new Singleton() 仅被调用一次,并且仅在实际使用Singleton.Instance 时才被调用。

【讨论】:

  • 值得注意的是,使构造函数protected 将允许类被继承,从而使其不是单例。
  • @Sriram 当然,它也可能是private。 :)
猜你喜欢
  • 2022-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-25
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
相关资源
最近更新 更多