Jon Skeet澄清了Singleton

public sealed class Singleton
{
    Singleton() {}

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

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested() {}
        internal static readonly Singleton instance = new Singleton();
    }
}

我希望在当前的C#应用​​程序中实现Jon Skeet的Singleton模式。

我对代码有两个疑问

  • 如何访问嵌套类中的外部类? 我的意思是

    internal static readonly Singleton instance = new Singleton();
    

    是什么叫封闭?

  • 我无法理解此评论

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    

    这个评论对我们有什么启示?


  • 不,这与封闭无关。 嵌套类可以访问其外部类的私有成员,包括这里的私有构造函数。

  • 阅读关于beforefieldinit的文章。 你可能希望或不希望没有操作的静态构造函数 - 这取决于你需要什么懒惰保证。 你应该知道,.NET 4在某种程度上改变了实际的类型初始化语义(仍然在规范中,但比以前更加细化)。

  • 你真的需要这种模式吗? 你确定你不能逃避:

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

    关于问题(1):Jon的回答是正确的,因为他隐含地将“嵌套”类私有标记为不公开或内部:-)。 你可以通过添加'private'来明确地做到这一点:

        private class Nested
    

    关于问题(2):基本上,关于beforeinitfield和类型初始化的文章告诉你,如果没有静态构造函数,运行时可以随时初始化它(但在使用它之前)。 如果你有一个静态构造函数,你在静态构造函数中的代码可能会初始化这些字段,这意味着只有当你询问类型时,运行时才允许初始化字段。

    因此,如果您不希望运行时在使用它们之前主动初始化字段,请添加一个静态构造函数。

    无论哪种方式,如果你正在实现单身人士,你可能希望它尽可能地懒惰初始化,而不是当运行时认为它应该初始化你的变量 - 或者你可能只是不在乎。 从你的问题,我想你想要他们尽可能晚。

    这让Jon见到了关于单身人士的帖子,这是IMO这个问题的基本主题。 哦,并怀疑:-)

    我想指出的是,他标记为“错误”的单身#3实际上是正确的(因为锁定在退出时自动暗示内存屏障)。 当你多次使用实例时(这或多或少是单例的:),它也应该比单例#2更快。 所以,如果你真的需要一个懒惰的单例实现,我可能会选择这个实现 - 原因很简单:(1)每个人都很清楚读取你的代码是怎么回事,(2)你知道会发生什么有例外。

    如果你想知道:我永远不会使用singleton#6,因为它可能很容易导致死锁和异常行为。 有关详细信息,请参阅:懒惰的锁定模式,特别是ExecutionAndPublication。

    链接地址: http://www.djcxy.com/p/9045.html

    上一篇: Singleton by Jon Skeet clarification

    下一篇: gwt serialization policy hosted mode out of sync