Wednesday, 30 October 2024

Static vs Singleton in C#

In C#, both static and singleton patterns are used to ensure a single, shared instance within a given application scope, but they differ in structure, use cases, and flexibility.

Static Class

A static class is a class that cannot be instantiated and is designed to hold static members only (fields, properties, and methods). It has a single instance in memory, accessible directly via the class name without creating an object.

Characteristics of a Static Class:

  • Cannot be instantiated: No instance can be created, and it cannot be passed as a parameter.
  • Single Instance: Only one instance exists automatically, accessible globally.
  • Only static members: All members must be static, meaning they belong to the class itself rather than instances.
  • No inheritance or interfaces: Static classes cannot inherit from or implement interfaces or other classes.
  • Memory management: Memory is allocated once, and it stays in memory for the lifetime of the application.

Use Cases:

  • Utility/helper classes, where you don’t need an instance (e.g., Math library in .NET).
  • Global constants and methods that don't depend on object state.

Example:

public static class Logger { public static void Log(string message) { Console.WriteLine(message); } } // Usage Logger.Log("Static class example");

Singleton Pattern

A singleton class is a class that allows only one instance to be created and provides a global point of access to that instance. Unlike a static class, it can implement interfaces, inherit from other classes, and have non-static members. Singleton instances are typically created using lazy initialization, where the instance is created only when it is needed.

Characteristics of a Singleton:

  • Single instance with controlled access: Only one instance exists, created on demand.
  • Encapsulated instance: Access to the instance is controlled through a public method or property.
  • Non-static members: The singleton can have non-static members and methods.
  • Implements interfaces and inherits: It can implement interfaces or inherit from other classes, making it more flexible than a static class.
  • Thread-safe initialization: Singleton implementations can be made thread-safe to ensure only one instance is created in multi-threaded environments.

Use Cases:

  • Managing shared resources like database connections, configuration settings, and caches.
  • Scenarios where the creation of multiple instances could result in conflicts or unwanted resource usage.

Example:

public sealed class DatabaseConnection { private static DatabaseConnection _instance; private static readonly object _lock = new object(); private DatabaseConnection() { } public static DatabaseConnection Instance { get { lock (_lock) { if (_instance == null) { _instance = new DatabaseConnection(); } return _instance; } } } public void Connect() { Console.WriteLine("Connecting to the database"); } } // Usage DatabaseConnection.Instance.Connect();

Summary Table

FeatureStatic ClassSingleton
InstantiationCannot be instantiatedOnly one instance, lazy-loaded
MembersOnly staticCan have both static and non-static
InheritanceCannot inherit or implement interfacesCan inherit and implement interfaces
Memory allocationAllocated on app loadAllocated only when needed
Use caseUtility classes, helper functionsShared resources, complex global state

When to Use Which

  • Use a static class when you need a simple, utility-style class with no instance data and no need for inheritance.
  • Use a singleton when you need a single instance with a global access point, especially if the class needs to manage state or implement interfaces.
Share:

0 comments:

Post a Comment