C# Constructors
Initializing objects when they are created
🔧 What are Constructors?
A constructor is a special method that runs automatically when an object is created. It initializes the object's fields and prepares it for use with initial values.
class Car
{
public Car() // Constructor
{
Console.WriteLine("Car created!");
}
}
Constructor Types
Default Constructor
No parameters, basic initialization
public Person()
{
Name = "Unknown";
}
Parameterized
Accepts values during creation
public Person(string name)
{
Name = name;
}
Copy Constructor
Creates copy of existing object
public Person(Person p)
{
Name = p.Name;
}
Static Constructor
Initializes static members once
static Person()
{
Count = 0;
}
🔹 Default Constructor
A default constructor is automatically provided if no constructor is defined in a class. It initializes an object with default values—typically null for references, zero for numeric types, and false for booleans. For example, when you create a Student object without arguments, it triggers the default constructor. This is essential for basic object instantiation in object‑oriented programming.
class Student
{
public string Name;
public int Grade;
// Default constructor
public Student()
{
Name = "New Student";
Grade = 0;
Console.WriteLine("Student object created!");
}
public void Display()
{
Console.WriteLine("Name: " + Name);
Console.WriteLine("Grade: " + Grade);
}
}
// Usage
Student student1 = new Student();
student1.Display();
Student student2 = new Student();
student2.Name = "Alice";
student2.Grade = 95;
student2.Display();
Output:
Student object created!
Name: New Student
Grade: 0
Student object created!
Name: Alice
Grade: 95
🔹 Parameterized Constructor
Parameterized constructors allow you to initialize objects with specific values at the time of creation. By accepting arguments, these constructors set initial states efficiently, avoiding separate property assignments. For instance, a Book class might accept title, author, and pages directly. This ensures objects are ready‑to‑use immediately after instantiation.
class Book
{
public string Title;
public string Author;
public int Pages;
// Parameterized constructor
public Book(string title, string author, int pages)
{
Title = title;
Author = author;
Pages = pages;
}
public void DisplayInfo()
{
Console.WriteLine("Title: " + Title);
Console.WriteLine("Author: " + Author);
Console.WriteLine("Pages: " + Pages);
Console.WriteLine();
}
}
// Usage - pass values during object creation
Book book1 = new Book("C# Programming", "John Smith", 450);
Book book2 = new Book("Learn OOP", "Jane Doe", 320);
book1.DisplayInfo();
book2.DisplayInfo();
Output:
Title: C# Programming
Author: John Smith
Pages: 450
Title: Learn OOP
Author: Jane Doe
Pages: 320
🔹 Constructor Overloading
Constructor overloading enables multiple constructors with different parameter lists within the same class. It provides flexible object creation options—like a Rectangle class that can be initialized with default dimensions, one side, or both sides. The compiler selects the appropriate constructor based on the arguments supplied, improving code usability and clarity.
class Rectangle
{
public double Width;
public double Height;
// Default constructor
public Rectangle()
{
Width = 1;
Height = 1;
}
// Constructor with one parameter (square)
public Rectangle(double side)
{
Width = side;
Height = side;
}
// Constructor with two parameters
public Rectangle(double width, double height)
{
Width = width;
Height = height;
}
public double GetArea()
{
return Width * Height;
}
}
// Usage - different ways to create objects
Rectangle rect1 = new Rectangle();
Rectangle rect2 = new Rectangle(5);
Rectangle rect3 = new Rectangle(4, 6);
Console.WriteLine("rect1 area: " + rect1.GetArea());
Console.WriteLine("rect2 area: " + rect2.GetArea());
Console.WriteLine("rect3 area: " + rect3.GetArea());
Output:
rect1 area: 1
rect2 area: 25
rect3 area: 24
🔹 Copy Constructor
A copy constructor creates a new object by copying the values from an existing object of the same class. It is especially useful when you need a duplicate that remains independent of the original. For example, cloning a Person object ensures changes to the copy do not affect the original. This supports deep‑copy scenarios in data‑sensitive applications.
class Person
{
public string Name;
public int Age;
// Regular constructor
public Person(string name, int age)
{
Name = name;
Age = age;
}
// Copy constructor
public Person(Person other)
{
Name = other.Name;
Age = other.Age;
Console.WriteLine("Copy created!");
}
public void Display()
{
Console.WriteLine(Name + " is " + Age + " years old");
}
}
// Usage
Person person1 = new Person("John", 30);
person1.Display();
// Create a copy of person1
Person person2 = new Person(person1);
person2.Display();
// Modify the copy
person2.Name = "Jane";
person2.Age = 25;
Console.WriteLine("\nAfter modification:");
person1.Display();
person2.Display();
Output:
John is 30 years old
Copy created!
John is 30 years old
After modification:
John is 30 years old
Jane is 25 years old
🔹 Static Constructor
Static constructors initialize static members of a class and execute only once—before any static member access or instance creation. They are ideal for one‑time setup tasks, such as loading configuration settings or establishing database connections. Because they run automatically and thread‑safely, static constructors ensure static data is ready before use.
class Database
{
public static string ConnectionString;
public static bool IsConnected;
// Static constructor
static Database()
{
ConnectionString = "Server=localhost;Database=myDB";
IsConnected = true;
Console.WriteLine("Database initialized!");
}
// Instance constructor
public Database()
{
Console.WriteLine("Database object created");
}
public static void ShowConnection()
{
Console.WriteLine("Connection: " + ConnectionString);
Console.WriteLine("Connected: " + IsConnected);
}
}
// Usage
Console.WriteLine("Before creating objects:");
Database.ShowConnection();
Console.WriteLine("\nCreating objects:");
Database db1 = new Database();
Database db2 = new Database();
Output:
Before creating objects:
Database initialized!
Connection: Server=localhost;Database=myDB
Connected: True
Creating objects:
Database object created
Database object created
🔹 Constructor Chaining
Constructor chaining allows one constructor to call another in the same class using the this keyword. This technique centralizes common initialization logic, reduces code duplication, and ensures consistency. For example, a multi‑parameter constructor can chain to a simpler one, setting default values for unspecified arguments and streamlining object setup.
class Employee
{
public string Name;
public int Id;
public decimal Salary;
// Constructor 1
public Employee() : this("Unknown", 0)
{
Console.WriteLine("Default constructor called");
}
// Constructor 2
public Employee(string name, int id) : this(name, id, 0)
{
Console.WriteLine("Two-parameter constructor called");
}
// Constructor 3 (main constructor)
public Employee(string name, int id, decimal salary)
{
Name = name;
Id = id;
Salary = salary;
Console.WriteLine("Three-parameter constructor called");
}
public void Display()
{
Console.WriteLine($"{Name} (ID: {Id}) - Salary: ${Salary}\n");
}
}
// Usage
Employee emp1 = new Employee();
emp1.Display();
Employee emp2 = new Employee("Alice", 101);
emp2.Display();
Employee emp3 = new Employee("Bob", 102, 50000);
emp3.Display();
Output:
Three-parameter constructor called
Two-parameter constructor called
Default constructor called
Unknown (ID: 0) - Salary: $0
Three-parameter constructor called
Two-parameter constructor called
Alice (ID: 101) - Salary: $0
Three-parameter constructor called
Bob (ID: 102) - Salary: $50000
🔹 Constructor Rules
Important Points:
- Same Name: Constructor name must match the class name
- No Return Type: Constructors don't have a return type (not even void)
- Automatic Call: Called automatically when object is created
- Can Be Overloaded: Multiple constructors with different parameters
- Access Modifiers: Can be public, private, protected, etc.
- Static Constructor: Runs once per class, not per object