C# 这两个单例实现之间的差异
我正在学习如何实现一些基本的设计模式。在学习Singleton模式时,我注意到web上有两种常见的实现:C# 这两个单例实现之间的差异,c#,design-patterns,C#,Design Patterns,我正在学习如何实现一些基本的设计模式。在学习Singleton模式时,我注意到web上有两种常见的实现: // Possibly from: http://www.yoda.arachsys.com/csharp/singleton.html // I cannot remember exact source, sorry :( public sealed class Singleton { // Static members are 'eagerly initialized', th
// Possibly from: http://www.yoda.arachsys.com/csharp/singleton.html
// I cannot remember exact source, sorry :(
public sealed class Singleton
{
// Static members are 'eagerly initialized', that is,
// immediately when class is loaded for the first time.
// .NET guarantees thread safety for static initialization
private static readonly Singleton instance = new Singleton();
// Private constructor prevents instantiation from other classes
private Singleton() { }
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
public static Singleton() { }
// Get the instance of the singleton
public static Singleton getInstance()
{
return instance;
}
}
以及:
就个人而言,在第一个示例中,我将实例字段公开,并省略getter。有兴趣知道这是否是一个坏主意吗?我不确定,但您似乎从这里得到了这些示例: 如果没有,请通读一遍。对这两个版本有一些想法。 如果你问我个人:如果我需要知道单例是否已经初始化,我会选择第二种解决方案
如果您不必处理多线程,我会使用一种更简单的方法(参见参考链接中的“坏代码”示例)。第一种方法是安全且懒惰的
静态构造函数
保证只执行一次,并且在第一次访问指令
之前立即执行。如果存在静态构造函数(即使为空),则静态字段初始化保证直接在静态构造函数之前执行。如果没有静态构造函数,字段初始化可能会更早发生
第二个是惰性的,但我不确定双锁模式是否像这样有效。我怀疑它坏了,至少在ECMA内存模型中是这样
就我个人而言,我会避免使用任何
类。实例单例模式,在大多数情况下都支持IoC单例模式。我肯定会支持您的第一个实现
第二个对我来说似乎有问题。。。如果您需要/想要一个懒惰的实现,您可以使用lazy
,因为它是框架的一部分,所以感觉更舒服
顺便说一句:有更多的方法来实现单例模式 它是一个单体,所以我会选择选项1,除非它是一个不总是需要的巨大物体。但是我可能不会为那些通常根本不用的东西创建一个单例。两种实现都很好,所以这取决于您需要什么
如果性能不是问题,请使用急切创建的第一个实例。否则,请使用第二个,其中只有第一个访问是同步的。可能的重复已被讨论过,并在博客上写到死。如果你使用.NET4,你可以选择使用Lazy()@henkholtman,我不这么认为。这个问题是问什么是一个好的实现,我问的是线程安全和示例用法:/WRT 1..access修饰符不允许用于静态构造函数。“。如果你问我个人:如果我需要知道单例是否已经初始化,我会选择第二个解决方案。”阅读你的链接。第二个例子在这里被列为断开。这里可能存在误解:链接文档的第二个版本=“第二个版本-简单线程安全”。但我同意,这并没有明确说明。今天早上我读了很多关于各种设计模式的东西,因为我正在用我所知道的所有语言实现它们,所以它可能来自那里。这只是我记下的两个。再次感谢您的链接:)坏代码坏是有原因的吗?为什么建议使用它?据我所知,“坏代码”指的是它不是多线程安全的。如果只有一个线程,则需要使其比所需的更复杂。从这个意义上说,我会推荐更简单/最简单的解决方案。感谢您提供的链接,看到使用Lazy的实现非常有趣。
:)您每天都会学到一些东西,我对所有关于单例的对话都感到非常厌倦,但我不知道Lazy。现在我期待着下一个关于单身汉的愚蠢面试问题。Thx Yahia.第一个懒惰的人是怎样的实例只在第一次访问.instance
.CodeInChaos时构造。CodeInChaos是正确的,直到我刚才检查,我还错误地认为静态是在类加载时初始化的。请原谅我是个书呆子,但你的意思是。举例来说,没有。举例。
public class Singleton
{
// Static, VOLATILE variable to store single instance
private static volatile Singleton m_instance;
// Static synchronization root object, for locking
private static object m_syncRoot = new object();
// Property to retrieve the only instance of the Singleton
public static Singleton Instance
{
get
{
// Check that the instance is null
if (m_instance == null)
{
// Lock the object
lock (m_syncRoot)
{
// Check to make sure its null
if (m_instance == null)
{
m_instance = new Singleton();
}
}
}
// Return the non-null instance of Singleton
return m_instance;
}
}
}