【问题标题】:Singleton implementation with empty static constructor具有空静态构造函数的单例实现
【发布时间】:2012-03-16 03:16:15
【问题描述】:

我正在经历here 中提到的以下单例实现。我了解静态构造函数在第一个静态方法调用之前或在实例化对象之前执行,但不了解它在这里的用途(甚至来自 cmets)。谁能帮我理解一下?

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;
        }
    }
}

【问题讨论】:

  • 它在它下面的项目符号中进行了解释,特别是:The laziness of type initializers is only guaranteed by .NET when the type isn't marked with a special flag called 'beforefieldinit'. Unfortunately, the C# compiler (as provided in the .NET 1.1 runtime, at least) marks all types which don't have a static constructor (i.e. a block which looks like a constructor but is marked static) as 'beforefieldinit'. 所以,他希望尽可能晚地(懒惰地)构造new Singleton(),这是获得 C# 编译器的唯一方法这样做是提供一个空的静态构造函数。
  • 原谅我的无知。什么是“类型初始化程序的惰性”。是在第一次请求时初始化吗?
  • 没错。只有在这种情况下才能保证,否则运行时可以随时运行类型初始化程序,例如在加载类型后立即运行。有关详细说明,请参阅 Jay 答案中的链接。

标签: c# singleton


【解决方案1】:

静态构造函数不是为了在其他任何事情之前或之后调用它,只是为了让编译器设置beforefieldinit标志。

更多信息在这里:What does beforefieldinit flag do?

基本原理是在单例对象的初始化中实现惰性度量。如果设置了beforefieldinit(因为没有定义静态构造函数),那么执行有条件引用Singleton.Instance 的方法很可能会初始化单例对象,即使条件不满足并且从未进行过调用。

public void Foo()
{
    if (false)
    {
        var bar = Singleton.Instance.SomeMethod();
    }
}

另一方面,如果beforefieldinit 没有设置(因为定义了一个静态构造函数——即使是一个空构造函数),那么执行相同的方法只会导致单例实例被初始化,如果条件满足并且那个电话是实际上打的。

那篇文章继续指出,这个特定的实现并不是完全惰性的,因为调用您在单例类上定义的任何 other 静态成员也会导致 Instance 被初始化。

【讨论】:

    猜你喜欢
    • 2016-09-21
    • 2011-04-19
    • 1970-01-01
    • 2015-08-06
    • 2013-03-05
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    • 2010-11-11
    相关资源
    最近更新 更多