Подтвердить что ты не робот

Почему для реализации singleton в С# 6.0 не нужен флаг beforefieldinit?

Я пытаюсь понять, почему это правильная реализация шаблона Singleton:

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

    private Singleton() { }

    // methods
}

Как насчет флага beforefieldinit? Согласно Jon Skeet article:

Лень инициализаторов типов гарантируется только .NET, когда тип не помечен специальным флагом, называемым beforefieldinit. К сожалению, компилятор С# (как указано в среде выполнения .NET 1.1) помечает все типы, у которых нет статического конструктора (т.е. Блок, который выглядит как конструктор, но помечен как статический), как beforefieldinit.

Не нужен ли статический конструктор в новейшей версии С#?

Код выше - это реализация SystemClock в проекте NodaTime, Джон Скит. '

ИЗМЕНИТЬ Код 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;
        }
    }
}
4b9b3361

Ответ 1

Оба являются правильными одноэлементными реализациями. Нужен ли вам статический конструктор, зависит только от того, насколько вы заботитесь о полной лености. Если вы действительно, действительно не хотите, чтобы синглтон был создан до тех пор, пока он не будет использован вызывающим, у вас должен быть статический конструктор - или используйте Lazy<T>. Вы также можете использовать статический конструктор в коде С# 6, конечно:

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

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

    // methods
}