Private Constructors and Singleton Classes in C#

A private constructor is a constructor that cannot be called from outside the class. It is primarily used in classes containing only static members or to implement the Singleton design pattern, which ensures that only one instance of a class can exist throughout the application's lifetime.

Syntax

Following is the syntax for declaring a private constructor −

class ClassName {
   private ClassName() {
      // private constructor body
   }
}

Private Constructor for Static-Only Classes

When a class contains only static members, a private constructor prevents instantiation of the class −

using System;

class MathHelper {
   // private constructor prevents instantiation
   private MathHelper() { }

   public static int Add(int a, int b) {
      return a + b;
   }

   public static int Multiply(int a, int b) {
      return a * b;
   }
}

class Program {
   public static void Main() {
      // MathHelper obj = new MathHelper(); // This would cause compile error
      
      int sum = MathHelper.Add(5, 3);
      int product = MathHelper.Multiply(4, 6);
      
      Console.WriteLine("Sum: " + sum);
      Console.WriteLine("Product: " + product);
   }
}

The output of the above code is −

Sum: 8
Product: 24

Singleton Pattern Implementation

The Singleton pattern ensures that only one instance of a class exists. It uses a private constructor combined with a static method to control instance creation −

Singleton Pattern Flow First Call Subsequent Calls Create Instance instance = null Return Existing instance != null Same instance returned every time Private constructor prevents external instantiation

Example

using System;

public class Singleton {
   private static Singleton instance = null;
   private static readonly object lockObject = new object();
   
   // Private constructor
   private Singleton() {
      Console.WriteLine("Singleton instance created");
   }
   
   public static Singleton GetInstance() {
      if (instance == null) {
         lock (lockObject) {
            if (instance == null) {
               instance = new Singleton();
            }
         }
      }
      return instance;
   }
   
   public void ShowMessage() {
      Console.WriteLine("Hello from Singleton!");
   }
}

class Program {
   public static void Main() {
      Singleton s1 = Singleton.GetInstance();
      Singleton s2 = Singleton.GetInstance();
      
      s1.ShowMessage();
      s2.ShowMessage();
      
      Console.WriteLine("Are both instances same? " + (s1 == s2));
   }
}

The output of the above code is −

Singleton instance created
Hello from Singleton!
Hello from Singleton!
Are both instances same? True

Simple Singleton Implementation

For single-threaded applications, a simpler singleton implementation can be used −

using System;

public class Logger {
   private static Logger instance = null;
   
   private Logger() {
      Console.WriteLine("Logger initialized");
   }
   
   public static Logger GetInstance() {
      if (instance == null) {
         instance = new Logger();
      }
      return instance;
   }
   
   public void Log(string message) {
      Console.WriteLine("Log: " + message);
   }
}

class Program {
   public static void Main() {
      Logger logger1 = Logger.GetInstance();
      Logger logger2 = Logger.GetInstance();
      
      logger1.Log("First message");
      logger2.Log("Second message");
      
      Console.WriteLine("Same instance: " + (logger1 == logger2));
   }
}

The output of the above code is −

Logger initialized
Log: First message
Log: Second message
Same instance: True

Comparison

Private Constructor Use Case Purpose Example
Static-Only Classes Prevent instantiation of utility classes Math helper, configuration classes
Singleton Pattern Control instance creation to ensure only one exists Database connections, loggers, caches

Conclusion

Private constructors in C# serve two main purposes: preventing instantiation of static-only utility classes and implementing the Singleton design pattern. The Singleton pattern ensures only one instance of a class exists, making it useful for managing shared resources like database connections or application configuration.

Updated on: 2026-03-17T07:04:35+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements