Singleton design pattern: Eager/Lazy Singleton
Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio
| C# Design Patterns |
|
| edit |
Instantiation means creating an object using a class as a template. There are two approaches to instantiation: lazy instantiation and eager instantiation. Actually, we just saw the lazy kind on the previous page.
Lazy Singleton design pattern
"Lazy instantiation" refers to the fact that a class is not instantiated until a request is made via the Singleton.Instance() method. This means that the overhead of creating the object is put off until the very last second—until another class needs to call one of the Singleton methods. You might want to use lazy instantiation in order to make an application start up more quickly by delaying some of the overhead until absolutely necessary. Or, you might not be sure the Singleton would be needed at all; therefore, why load it until it is needed?
Here is the lazy instantiation code from the previous example;
if (singleton == null) { singleton = new Singleton(); // lazy Console.WriteLine ("Singleton instantiated"); }
This code is quite simple. If singleton is null, then the Singleton object has not yet been instantiated. And, if not, it is instantiated with the new operator. This is only done once; because, the next time the code is called, singleton will not be null.
Eager Singleton design pattern
"Eager instantiation" is still lazy, but not as lazy as the previous example. The laziness in this implementation depends on .NET, which will run the initializers whenever the class is instantiated or another static member is accessed.
The only differences between this eager code and the previous lazy example is that Singleton is instantiated in the static initializer instead of in the Singleton.Instance() method; and, there is a static constructor. However, this implementation is thread safe.
C# example of eager Singleton design pattern (thread-safe):
using System; public sealed class Singleton { //private static Singleton singleton; private static readonly Singleton singleton = new Singleton(); // eager static Singleton() { Console.WriteLine ("Singleton instantiated"); } private Singleton() {} // private constructor public static Singleton GetInstance() { //if (singleton == null) //{ // singleton = new Singleton(); // Console.WriteLine ("Singleton instantiated"); //} return singleton; } }
Notes on the eager Singleton design pattern
- The
staticmodifier on the constructor is required for laziness; because, .NET guarantees the laziness of type initializers only when they are not marked with thebeforefieldinitflag. And, all types without static constructors are markedbeforefieldinitby the C# compiler. So, it might be a good idea to move the initializer to the static constructor; so, you won't forget the static constructor. - If there are multiple
staticmembers, the first reference to any of those members will trigger the type initializers. Also, class instatiation will trigger them. - It is not necessary to mark the
singletonvariable asreadonly; since, it isprivate. But, it is customary since the initializer is evaluated at runtime. - In this implementation, the
getInstancemethod could be dispensed with if thesingletonvariable is madepublic.
- The
|

