具有可触发初始化的C#Singleton模式

前端之家收集整理的这篇文章主要介绍了具有可触发初始化的C#Singleton模式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_404_1@我需要一个单身人士:

>是懒惰加载
>是线程安全的
>在施工时加载一些值
>可以随时查询这些值
>初始化可能在查询开始之前的某个精确时间发生 – 所以我必须能够以某种方式从外部触发它.当然,多次触发应该只进行一次初始化.

我使用.NET 3.5.

我使用静态子类开始使用Jon Skeet的implementation(第5版):

public sealed class Singleton
{
    IEnumerable<string> Values {get; private set;}
    private Singleton()
    {
        Values = new[]{"quick","brown","fox"};
    }

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

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

        internal static readonly Singleton instance = new Singleton();
    }
}

除了“从外部触发初始化”之外,几乎所有方框都会打勾.由于实际初始化发生在ctor内部,因此不会发生多次.

如何实现这一目标?

单例将使用如下:

public static void Main(){

    //do stuff,singleton should not yet be initialized.

    //the time comes to initialize the singleton,e.g. a database connection is available
    //this may be called 0 or more times,possibly on different threads

    Singleton.Initialize();
    Singleton.Initialize();
    Singleton.Initialize();

    //actual call to get retrieved values,should work
    var retrieveVals = Singleton.Instance.Values;

}

解决方法

好像你可以这样做:
public sealed class Singleton
{
    IEnumerable<string> Values {get; private set;}
    private Singleton(bool loadDefaults)
    {
        if (loadDefaults)
            Values = new[]{"quick","fox"};
        else
            Values = new[]{"another","set","of","values"};
    }

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

    public static void Initialize() {
        Nested.Initialize();
    }

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

        internal static readonly Singleton instance = new Singleton(true);
        private static object instanceLock = new object();
        private static bool isInitialized = false; 

        public static void Initialize() {
            lock(instanceLock) {
                if (!isInitialized) {
                    isInitialized = true;
                    instance = new Singleton(false);
                }
            }
        }

    }
}

或者创建一个将要更新的单个实例:

public sealed class Singleton
{
    IEnumerable<string> Values {get; private set;}
    private Singleton()
    {
        Values = new[]{"quick","fox"};
    }

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

    private static object instanceLock = new object();
    private static bool isInitialized = false; 

    public static void Initialize() {
        lock(instanceLock) {
            if (!isInitialized) {
                isInitialized = true;
                Instance.Values = new[]{"another","values"};
            }
        }
    }

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

        internal static readonly Singleton instance = new Singleton();
    }
}

第三个变体基于您的不可变注释和删除嵌套类注释:

public sealed class Singleton
{
    IEnumerable<string> Values {get; private set;}
    private Singleton()
    {
        Values = new[]{"quick","fox"};
    }

    private static Singleton instance;
    private static object instanceLock = new object();

    public static Singleton Instance {
        get {
            Initialize();
            return instance;
        }
     }

    public static void Initialize() {
        if (instance == null) {
            lock(instanceLock) {
                if (instance == null)
                    instance = new Singleton();
            }
        }
    }
}
原文链接:https://www.f2er.com/c/117835.html

猜你在找的C&C++相关文章