简体   繁体   English

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

[英]Why the singleton implementation in C# 6.0 does not need the beforefieldinit flag?

I'm trying to understand why this is a correct implementation of the Singleton pattern: 我试图理解为什么这是Singleton模式的正确实现:

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

    private Singleton() { }

    // methods
}

What about the beforefieldinit flag? 那么beforefieldinit旗帜怎么样? According to Jon Skeet article : 根据Jon Skeet的文章

The laziness of type initializers is only guaranteed by .NET when the type isn't marked with a special flag called beforefieldinit. 类型初始值设定项的懒惰只有在未使用名为beforefieldinit的特殊标志标记类型时才由.NET保证。 Unfortunately, the C# compiler (as provided in the .NET 1.1 runtime, at least) marks all types which don't have a static constructor (ie a block which looks like a constructor but is marked static) as beforefieldinit. 不幸的是,C#编译器(至少在.NET 1.1运行时中提供)标记所有没有静态构造函数的类型(即看起来像构造函数但被标记为静态的块)作为beforefieldinit。

Is the static constructor not needed in the newest version of C#? 最新版本的C#中不需要静态构造函数吗?

The code above is the implementation of SystemClock in NodaTime project, by Jon Skeet.' 上面的代码是Jon Skeet在NodaTime项目中实现的SystemClock

EDIT Jon Skeet code for reference (why I'm mentioning this beforefieldinit flag): 编辑 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;
        }
    }
}

Both are correct singleton implementations. 两者都是正确的单例实现。 Whether you need the static constructor just depends on how much you care about full laziness. 无论您需要静态构造函数只是取决于你有多在乎满懒惰。 If you really, really don't want the singleton to be instantiated until it's used by a caller, you should have a static constructor - or use Lazy<T> . 如果你真的,真的不希望单例实例化,直到它被调用者使用,你应该有一个静态构造函数 - 或者使用Lazy<T> You can use a static constructor in the C# 6 code as well, of course: 当然,您也可以在C#6代码中使用静态构造函数:

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

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

    // methods
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM