为什么C#6.0中的单例实现不需要beforefieldinit标志?

时间:2016-03-21 14:47:36

标签: c# singleton

我试图理解为什么这是Singleton模式的正确实现:

public sealed class Singleton : ISingleton
{
    public static Singleton Instance { get; } = new Singleton();

    private Singleton() { }

    // methods
}

beforefieldinit旗帜怎么样?根据Jon Skeet article

  

类型初始值设定项的懒惰仅在类型未使用名为beforefieldinit的特殊标志标记时由.NET保证。不幸的是,C#编译器(至少在.NET 1.1运行时中提供)标记所有没有静态构造函数的类型(即看起来像构造函数但被标记为静态的块)为beforefieldinit。

最新版本的C#中不需要静态构造函数吗?

上面的代码是Jon Skeet在NodaTime项目中SystemClock的实现。'

修改 Jon Skeet代码供参考(为什么我提到这个beforefieldinit标志):

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

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    private Singleton()
    {
    }

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

1 个答案:

答案 0 :(得分:10)

两者都是正确的单例实现。是否需要静态构造函数只是取决于你对完全懒惰的关注程度。如果你真的,真的不希望单例实例化,直到调用者使用它,你应该有一个静态构造函数 - 或者使用Lazy<T>。当然,您也可以在C#6代码中使用静态构造函数:

public sealed class Singleton : ISingleton
{
    public static Singleton Instance { get; } = new Singleton();

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

    // methods
}