What's the Difference Between Static Class vs. Singleton Patterns in C#?
Discover the differences between the singleton design pattern and the static keyword on C# classes for storing common data.
Join the DZone community and get the full member experience.
Join For FreeWhen developing apps with C# in the .NET framework, you have a choice between two single, shared class instances. Whether you decide to use a static keyword or a singleton design pattern depends on several factors, which are outlined in the article below.
Key Differences Between Static Classes and Singleton Patterns
Put simply, a singleton is a pattern while a static class is a keyword. This means you can create one, persistent instance across an application’s entire lifespan with a singleton. The nifty thing about singletons is that a single instance can be used as a parameter for other methods. On the other hand, static classes only permit static methods and can’t be passed as parameters.
Other key differences include:
Singletons can inherit from other classes, implement interfaces and permit inheritance, making them more flexible than static classes.
You can implement singletons asynchronously or lazily, and the .NET framework CLR can automatically load it.
Singletons follow Object-Oriented Principles, letting you handle them polymorphically without forcing users to assume there’s only a single instance.
Singletons can dispose but static classes can’t.
Static classes are stored in the stack while singletons are stored on the heap.
Singletons can clone while static classes can’t.
Singletons can have a private constructor.
The Singleton Pattern
Most developers agree the singleton design pattern is the ideal solution. They let you design classes that require a single instance, such as manager classes, for use in caching, thread pools, and logging. They’re also great for managing shared resources such as printer spooling, where you need to avoid conflicting requests for a single resource.
Below is an implementation of a singleton that I’ve used before. As you know, a singleton is a highly-efficient, graceful single-instance object. One of its main features is that it has a static property that you must access to get the object reference.
/// <summary>/// Sample singleton object./// </summary>public sealed class SiteStructure{ /// <summary> /// Possible an expensive resource we need to only store in one place. /// </summary> object[] _data = new object[10]; /// <summary> /// Allocate ourselves. We have a private constructor, so no one else can. /// </summary> static readonly SiteStructure _instance = new SiteStructure(); /// <summary> /// Access SiteStructure.Instance to get the singleton object. /// Then call methods on that instance. /// </summary> public static SiteStructure Instance { get { return _instance; } } /// <summary> /// This is a private constructor, meaning no outsides have access. /// </summary> private SiteStructure() { // Initialize members, etc. here. }}
What Is a Static Class?
A static class is a class that can’t be instantiated but also doesn’t require you to fiddle around creating instances for each new object. They consume fewer resources, and you won’t need to duplicate the same class in memory. This makes it a handy container for sets of methods that exclusively operate on output parameters and don’t have to set or get any internal instance fields. If you only require a utility class with several utility methods, a static class’s simple implementation can improve app performance, making it a better option.
Its major disadvantage in comparison to singleton patterns is that you can’t change how it behaves once the class is decorated with the static keyword. However, the singleton pattern’s prowess doesn’t end there. Let’s take a look at the major differences between the two class instances.
Static Class Example
In the following example, take a look at how I use a static keyword on the class and constructor. Static classes may be less fiddly, but the singleton example has many important advantages, which we’ll take a look at after this code block.
/// <summary>/// Static class example. Pay heed to the static keywords./// </summary>static public class SiteStatic{ /// <summary> /// The data must be a static member in this example. /// </summary> static object[] _data = new object[10]; /// <summary> /// C# doesn't define when this constructor is run, but it will /// be run right before it is used most likely. /// </summary> static SiteStatic() { // Initialize all of our static members. }}
You can use static classes to store single-instance, global data. The class can be initialized at any time, but in my experience, it’s initialized lazily — in other words, at the last possible moment. As such, you might lose control over the exact behavior of the class by using a static class.
Singleton Advantages in Action
Singletons preserve the conventional class approach and don't require that you use the static keyword everywhere. They may be more demanding to implement at first, but they greatly simplify your program’s architecture. Unlike static classes, it’s possible to use singletons as parameters or objects.
// We want to call a function with this structure as an object.// Get a reference from the Instance property on the singleton.{ SiteStructure site = SiteStructure.Instance; OtherFunction(site); // Use singleton as parameter.}
Interface Inheritance
In C#, an interface is a contract, and objects that have an interface must meet every requirement of that interface. Usually, the requirements are a subset of the object in question. Here’s how we can use a singleton with an interface, which is called ISiteInterface
in the example.
/// <summary>/// Stores signatures of various important methods related to the site./// </summary>public interface ISiteInterface{};/// <summary>/// Skeleton of the singleton that inherits the interface./// </summary>class SiteStructure : ISiteInterface{ // Implements all ISiteInterface methods. // [omitted]}/// <summary>/// Here is an example class where we use a singleton with the interface./// </summary>class TestClass{ /// <summary> /// Sample. /// </summary> public TestClass() { // Send singleton object to any function that can take its interface. SiteStructure site = SiteStructure.Instance; CustomMethod((ISiteInterface)site); } /// <summary> /// Receives a singleton that adheres to the ISiteInterface interface. /// </summary> private void CustomMethod(ISiteInterface interfaceObject) { // Use the singleton by its interface. }}
Now we can reuse our singleton for any of the implementations of interface-conforming objects. There may be 1, 2, or 10. We don't need to rewrite anything over and over again. We store state more conventionally, use objects by their interfaces, and can use traditional object-oriented programming best practices. Reusing code can control the object state much more easily. This facilitates greatly improved code-sharing and an infinitely cleaner body of code.
Conclusion
With less code, your programs tend to have fewer bugs and are easier to maintain. Other advantages of singleton patterns over static classes are:
Testability: Testing singleton patterns is much easier than static classes
Memory management: Using a singleton class lets you take advantage of garbage collection for managed objects
Dependency injection: You can’t use constructor injection with static classes, but you can with singletons
Extensibility: You can have extension methods with a singleton class but not a static class
If you want to learn more about singleton vs. static, "C# Design Patterns" by Judith Bishop is a worthwhile read.
Published at DZone with permission of Sam Allen. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments