Singleton没有密封的类和线程安全问题

时间:2019-06-21 13:52:46

标签: c# .net c#-4.0 singleton private-constructor

我被要求在今天的采访中写辛格尔顿。我写了以下内容,请注意,我使用“属性设置”方法进行设置,然后使用“获取”方法返回了实例。但是我在互联网上看到他们使用的大多数地方都只能得到,也就是说,我在下面所做的事情是错误的?抱歉,我现在没有VS ide来验证它,因此请在此处发布。

此外,一些使用的密封类包括私有构造函数。为什么要用私人弊端密封?

let (left, right) = x.split_at_mut(mid);
for (l, r) in Iterator::zip(left.iter_mut(), right.iter_mut()) {
    std::mem::swap(l, r);
}
assert_eq!(&x, &[4, 5, 6, 1, 2, 3]);

2 个答案:

答案 0 :(得分:0)

我的建议是尝试自己编译和运行代码。到目前为止,这是了解其工作原理的最简单方法。

如果您尝试构建代码,则会出现以下错误:

Error   CS0198  A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

换句话说,您应该在构造函数中实例化实例。

关于您的问题,需要一个私有的构造函数来防止从您的类外部进行访问,并且这足以确保其他类不能从您的类继承。您真的不需要密封。

您可以找到有关{@ {3}}的单例模式的非常好的摘要

答案 1 :(得分:0)

@Learner由于是面试问题,而且在印度大部分地区,他们要求写Psuedo代码以评估候选人的编码技能,所以我尝试使自己适应候选人的鞋子,以给出答案。

随着编程语言的发展,良好的设计模式已经发展了一段时间,Singleton也不例外。我们可以使用多种方法使用C#创建Singleton类。我想展示一些我能回忆的口味

1。没有线程安全性的普通香草Singleton

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

2。辛格尔顿·瑟夫特(Single)

public sealed class Singleton_ThreadLock
{  
    Singleton_ThreadLock()  
    {  
    }  
    private static readonly object padlock = new object();  
    private static Singleton_ThreadLock instance = null;  
    public static Singleton_ThreadLock Instance  
    {  
        get  
        {  
        // Uses the lock to avoid another resource to create the instance in parallel
            lock (padlock)  
            {  
                if (instance == null)  
                {  
                    instance = new Singleton_ThreadLock();  
                }  
                return instance;  
            }  
        }  
    }  
} 

3。单例-双线程安全

public sealed class Singleton_DoubleThreadSafe  
{  
    Singleton_DoubleThreadSafe()  
    {  
    }  
    private static readonly object padlock = new object();  
    private static Singleton_DoubleThreadSafe instance = null;  
    public static Singleton_DoubleThreadSafe Instance  
    {  
        get  
        {  
            if (instance == null)  
            {  
                lock (padlock)  
                {  
                    if (instance == null)  
                    {  
                        instance = new Singleton_DoubleThreadSafe();  
                    }  
                }  
            }  
            return instance;  
        }  
    }  
}

4。 Singleton-早期初始化

public sealed class Singleton_EarlyInitialization  
{  
    private static readonly Singleton_EarlyInitialization instance = new Singleton_EarlyInitialization();
    // Explicit static constructor to tell C# compiler  
    // not to mark type as beforefieldinit  
    static Singleton_EarlyInitialization()  
    {  
    }  
    private Singleton_EarlyInitialization()  
    {  
    }  
    public static Singleton_EarlyInitialization Instance  
    {  
        get  
        {  
            return instance;  
        }  
    }  
}  

5。使用.Net 4.0+框架的Singleton-延迟初始化

public sealed class Singleton  
{  
    private Singleton()  
    {  
    }  
    private static readonly Lazy<Singleton> lazy = new Lazy<Singleton>(() => new Singleton());  
    public static Singleton Instance  
    {  
        get  
        {  
            return lazy.Value;  
        }  
    }  
}

注意事项:

  1. 很少有人使用反射来创建类的实例(我在一个框架中做了),但也可以避免。网络中很少有样本可以显示如何避免这种情况
  2. 始终将Singleton类设置为密封的最佳做法,因为这将限制开发人员继承该类。
  3. 市场上有很多IOC可以创建普通类的Singleton实例,而无需遵循上述Singleton实现。