Paramclasses Academy - Blog

Tutorials Details

←
Post 14 of 30
→

What is Constructors in C# ? Examplan Types, Uses and Practical

What is Constructors in C# ? Examplan Types, Uses and Practical

October 26, 2026

Introduction

Constructors are an important concept in C# and Object-Oriented Programming (OOP). They help initialize objects when they are created and ensure that an object starts with the required data.

When you create an object using the new keyword, C# invokes an appropriate constructor. Constructors are commonly used to initialize fields and properties, validate input, and prepare an object for use.

For example, when creating a student object, you may want to provide the student's name, roll number, and age immediately. A constructor allows you to initialize these values during object creation rather than assigning them separately afterward.

In this tutorial, you will learn the different types of constructors in C#, how constructor overloading works, how to use constructor chaining, and how constructors are applied in practical programs.

What You Will Learn

  • What a constructor is in C#

  • Constructor syntax and rules

  • Default and parameterless constructors

  • Parameterized constructors

  • Constructor overloading

  • Copy-style constructors

  • Static constructors

  • Private constructors

  • Constructor chaining using this and base

  • Object initialization and constructor execution

  • Practical examples and common mistakes

1. What Is a Constructor in C#?

A constructor is a special member of a class or struct that is invoked when an instance is created. Its main purpose is to initialize the new object.

A constructor has the same name as its containing class and does not specify a return type, not even void.

Basic Example

using System;

class Student
{
    public string Name;
    public int Age;

    public Student()
    {
        Name = "Unknown";
        Age = 18;
    }

    public void DisplayInfo()
    {
        Console.WriteLine($"Name: {Name}");
        Console.WriteLine($"Age: {Age}");
    }
}

class Program
{
    static void Main()
    {
        Student student = new Student();
        student.DisplayInfo();
    }
}

Output:

Name: Unknown
Age: 18

How It Works

  • Student is the class name.

  • Student() is the constructor.

  • Name and Age are initialized inside the constructor.

  • new Student() creates an instance and invokes the parameterless constructor.

  • DisplayInfo() prints the initialized values.

The constructor executes automatically as part of instance creation. You do not call an instance constructor like an ordinary method.

2. Rules of Constructors in C#

Keep these important rules in mind when writing constructors:

  1. The constructor name must match the class or struct name.

  2. A constructor does not declare a return type.

  3. Constructors can accept parameters.

  4. Constructors can be overloaded using different parameter lists.

  5. Instance constructors can have access modifiers such as public, private, or protected, subject to the type and declaration rules.

  6. Constructors are invoked during object creation, rather than being called as ordinary instance methods.

  7. Constructors are not inherited by derived classes.

  8. A constructor can call another constructor in the same type using this(...).

  9. A derived-class constructor can invoke a base-class constructor using base(...).

  10. If a class declares no instance constructor, the compiler generally provides an implicit parameterless constructor, subject to the applicable C# rules.

3. Types of Constructors in C#

C# supports several constructor patterns. The most useful ones to understand are listed below.

Constructor type Purpose
Parameterless constructor Initializes an object without requiring arguments.
Default constructor Commonly refers to the implicit parameterless constructor supplied by the compiler when no instance constructor is declared.
Parameterized constructor Accepts arguments to initialize an object.
Copy-style constructor Creates an object using values from another object; this is a pattern you implement yourself in C#.
Static constructor Initializes static state for a type.
Private constructor Restricts external instance creation through that constructor.
Constructor with chaining Delegates initialization to another constructor using this(...) or base(...).

These names describe common patterns and language features. For example, a parameterless constructor that you explicitly write is not the same thing as the implicit default constructor generated by the compiler.

4. Default Constructor in C#

When a class does not declare any instance constructors, C# generally supplies an implicit parameterless constructor.

Consider this example:

using System;

class Employee
{
    public string Name;
    public int Salary;
}

class Program
{
    static void Main()
    {
        Employee employee = new Employee();

        Console.WriteLine(employee.Name == null);
        Console.WriteLine(employee.Salary);
    }
}

Typical output:

True
0

The reference-type field Name initially has a null value, and the int field Salary has the default value 0.

The implicit constructor does not automatically assign meaningful business values such as an employee's name or salary. It provides the ability to create an instance without supplying constructor arguments.

Important: If you declare your own instance constructor, the compiler does not also generate the implicit parameterless constructor. If you still need to create objects without arguments, declare a parameterless constructor explicitly.

5. Parameterless Constructor in C#

A parameterless constructor accepts no arguments. You can write one explicitly to provide meaningful initial values.

using System;

class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }

    public Product()
    {
        Name = "New Product";
        Price = 0;
    }
}

class Program
{
    static void Main()
    {
        Product product = new Product();

        Console.WriteLine(product.Name);
        Console.WriteLine(product.Price);
    }
}

Output:

New Product
0

When Should You Use a Parameterless Constructor?

A parameterless constructor can be useful when:

  • An object has sensible default values.

  • A framework or library requires parameterless construction.

  • You want to create an object first and configure it afterward.

  • The object can be valid without additional input.

However, if the object requires essential data to be valid, a parameterized constructor may be a better design.

6. Parameterized Constructor in C#

A parameterized constructor accepts arguments that provide the initial values for an object.

This is useful when different objects need different starting values.

using System;

class Student
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Student(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public void Display()
    {
        Console.WriteLine($"Name: {Name}, Age: {Age}");
    }
}

class Program
{
    static void Main()
    {
        Student student1 = new Student("Rahul", 20);
        Student student2 = new Student("Priya", 22);

        student1.Display();
        student2.Display();
    }
}

Output:

Name: Rahul, Age: 20
Name: Priya, Age: 22

Explanation

  • string name and int age are constructor parameters.

  • "Rahul" and 20 are arguments supplied when creating the first object.

  • The constructor assigns the arguments to the object's properties.

  • Each instance receives its own initial values.

Constructor Validation

Constructors can also validate input so that invalid objects are not created.

using System;

class Product
{
    public string Name { get; }
    public decimal Price { get; }

    public Product(string name, decimal price)
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            throw new ArgumentException(
                "Product name is required.", nameof(name));
        }

        if (price < 0)
        {
            throw new ArgumentOutOfRangeException(
                nameof(price), "Price cannot be negative.");
        }

        Name = name;
        Price = price;
    }
}

Here, the constructor rejects a missing product name or a negative price by throwing an exception. This helps protect the object's state from invalid initial values.

7. Constructor Overloading in C#

Constructor overloading means defining multiple constructors in the same class with different parameter lists.

Each constructor can support a different way of creating an object.

using System;

class Employee
{
    public string Name { get; set; }
    public int Age { get; set; }
    public decimal Salary { get; set; }

    public Employee()
    {
        Name = "Unknown";
        Age = 18;
        Salary = 0;
    }

    public Employee(string name)
    {
        Name = name;
        Age = 18;
        Salary = 0;
    }

    public Employee(string name, int age, decimal salary)
    {
        Name = name;
        Age = age;
        Salary = salary;
    }

    public void Display()
    {
        Console.WriteLine(
            $"{Name}, Age: {Age}, Salary: {Salary}");
    }
}

class Program
{
    static void Main()
    {
        Employee employee1 = new Employee();
        Employee employee2 = new Employee("Amit");
        Employee employee3 = new Employee("Neha", 28, 55000);

        employee1.Display();
        employee2.Display();
        employee3.Display();
    }
}

Output:

Unknown, Age: 18, Salary: 0
Amit, Age: 18, Salary: 0
Neha, Age: 28, Salary: 55000

The compiler selects the constructor whose parameter list matches the supplied arguments.

Constructor overloading is useful when your class supports multiple valid ways of initializing an object.

8. Constructor Chaining Using this

Constructor chaining allows one constructor to call another constructor in the same class. In C#, you use this(...) for this purpose.

It helps reduce repeated initialization logic.

using System;

class Employee
{
    public string Name { get; }
    public int Age { get; }
    public decimal Salary { get; }

    public Employee() : this("Unknown", 18, 0)
    {
    }

    public Employee(string name) : this(name, 18, 0)
    {
    }

    public Employee(string name, int age, decimal salary)
    {
        Name = name;
        Age = age;
        Salary = salary;
    }

    public void Display()
    {
        Console.WriteLine(
            $"{Name}, Age: {Age}, Salary: {Salary}");
    }
}

class Program
{
    static void Main()
    {
        Employee employee1 = new Employee();
        Employee employee2 = new Employee("Rahul");
        Employee employee3 = new Employee("Priya", 25, 60000);

        employee1.Display();
        employee2.Display();
        employee3.Display();
    }
}

How It Works

  • Employee() delegates to the three-parameter constructor.

  • Employee(string name) also delegates to the three-parameter constructor.

  • The final constructor performs the actual property initialization.

This avoids maintaining the same initialization code in several places.

Important: A constructor initializer such as this(...) must appear in the constructor declaration. Avoid creating circular constructor chains, because they are not valid.

9. Base-Class Constructor Using base

When one class inherits from another, the derived class can invoke a base-class constructor using base(...).

using System;

class Person
{
    public string Name { get; }

    public Person(string name)
    {
        Name = name;
    }
}

class Student : Person
{
    public int RollNumber { get; }

    public Student(string name, int rollNumber)
        : base(name)
    {
        RollNumber = rollNumber;
    }

    public void Display()
    {
        Console.WriteLine($"Name: {Name}");
        Console.WriteLine($"Roll Number: {RollNumber}");
    }
}

class Program
{
    static void Main()
    {
        Student student = new Student("Rahul", 101);
        student.Display();
    }
}

Output:

Name: Rahul
Roll Number: 101

Explanation

  • Person is the base class.

  • Student inherits from Person.

  • base(name) invokes the base-class constructor with the supplied name.

  • The Student constructor initializes the additional RollNumber property.

This technique is useful when a derived object needs to initialize the state defined by its parent class.

10. Copy-Style Constructor in C#

C# does not provide a special built-in copy constructor in the same way some other languages do. However, you can define a constructor that accepts another object of the same type and copies its values.

using System;

class Student
{
    public string Name { get; set; }
    public int Marks { get; set; }

    public Student(string name, int marks)
    {
        Name = name;
        Marks = marks;
    }

    public Student(Student other)
    {
        if (other == null)
        {
            throw new ArgumentNullException(nameof(other));
        }

        Name = other.Name;
        Marks = other.Marks;
    }

    public void Display()
    {
        Console.WriteLine($"{Name}: {Marks}");
    }
}

class Program
{
    static void Main()
    {
        Student original = new Student("Amit", 85);
        Student copy = new Student(original);

        copy.Name = "Neha";

        original.Display();
        copy.Display();
    }
}

Output:

Amit: 85
Neha: 85

The constructor creates a separate Student object and copies the two property values.

This is a shallow value copy for the properties shown. If a class contains references to mutable objects, simply copying those references does not create independent copies of the referenced objects. Deep copying requires additional design decisions.

11. Static Constructor in C#

A static constructor initializes static state for a type. It has the class name preceded by static, takes no parameters, and has no access modifier.

using System;

class ApplicationSettings
{
    public static string ApplicationName { get; }

    static ApplicationSettings()
    {
        ApplicationName = "Student Management System";

        Console.WriteLine("Static constructor executed.");
    }
}

class Program
{
    static void Main()
    {
        Console.WriteLine(ApplicationSettings.ApplicationName);
        Console.WriteLine(ApplicationSettings.ApplicationName);
    }
}

Typical output:

Static constructor executed.
Student Management System
Student Management System

Important Characteristics

  • A static constructor is executed automatically by the runtime.

  • It is used to initialize static fields or other static state.

  • It cannot accept parameters.

  • It cannot have an access modifier.

  • It is not called directly by application code.

  • A type's static constructor is executed at most once per application domain or corresponding runtime type initialization context.

The exact timing of static initialization depends on the type's initialization semantics. Do not rely on it for work that must happen at a precisely controlled point in application startup.

12. Private Constructor in C#

A private constructor prevents code outside the class from invoking that constructor directly. It can be useful when a class controls its own instance creation or when the type is designed to expose only static functionality.

using System;

class MathHelper
{
    private MathHelper()
    {
    }

    public static int Square(int number)
    {
        return number * number;
    }
}

class Program
{
    static void Main()
    {
        Console.WriteLine(MathHelper.Square(5));
    }
}

Output:

25

The MathHelper class provides a static operation and does not need to be instantiated in this example.

A private constructor is also sometimes used in singleton-style designs or factory-based designs. However, a private constructor alone does not automatically implement the Singleton pattern; the class must also control how its instance is created and shared.

13. Constructor vs Method in C#

Constructors and methods can both contain executable code, but they serve different purposes.

Constructor Method
Initializes an instance or type. Performs an operation.
Has the name of the class or struct. Can have any valid method name.
Does not declare a return type. Declares a return type, including void.
An instance constructor is invoked during instance creation. Called explicitly or through another supported invocation mechanism.
Can be overloaded. Can also be overloaded.
Cannot be inherited as a constructor. Ordinary instance methods can be inherited, subject to access and member rules.

Example:

class Calculator
{
    public int Number { get; }

    public Calculator(int number)
    {
        Number = number;
    }

    public int DoubleNumber()
    {
        return Number * 2;
    }
}

Usage:

Calculator calculator = new Calculator(10);

Console.WriteLine(calculator.DoubleNumber());

Output:

20

The constructor initializes the object, while DoubleNumber() performs an operation on its state.

14. Constructor and Object Initializer

A constructor and an object initializer can work together.

using System;

class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }

    public Product(string name)
    {
        Name = name;
    }
}

class Program
{
    static void Main()
    {
        Product product = new Product("Keyboard")
        {
            Price = 1500
        };

        Console.WriteLine(product.Name);
        Console.WriteLine(product.Price);
    }
}

Output:

Keyboard
1500

The constructor first initializes Name. After construction, the object initializer assigns Price.

This pattern is useful when some information is required during construction and other values can be configured afterward.

15. Practical Project: Student Registration System

Let's build a small example that uses constructors to initialize student information and calculate a student's result.

using System;
using System.Collections.Generic;

class Student
{
    public int RollNumber { get; }
    public string Name { get; }
    public int Marks { get; }

    public Student(int rollNumber, string name, int marks)
    {
        if (rollNumber <= 0)
        {
            throw new ArgumentOutOfRangeException(
                nameof(rollNumber));
        }

        if (string.IsNullOrWhiteSpace(name))
        {
            throw new ArgumentException(
                "Name is required.", nameof(name));
        }

        if (marks < 0 || marks > 100)
        {
            throw new ArgumentOutOfRangeException(
                nameof(marks),
                "Marks must be between 0 and 100.");
        }

        RollNumber = rollNumber;
        Name = name;
        Marks = marks;
    }

    public string GetResult()
    {
        return Marks >= 40 ? "Pass" : "Fail";
    }

    public void Display()
    {
        Console.WriteLine($"Roll Number: {RollNumber}");
        Console.WriteLine($"Name: {Name}");
        Console.WriteLine($"Marks: {Marks}");
        Console.WriteLine($"Result: {GetResult()}");
        Console.WriteLine("---------------------");
    }
}

class Program
{
    static void Main()
    {
        List<Student> students = new List<Student>
        {
            new Student(101, "Rahul", 85),
            new Student(102, "Priya", 92),
            new Student(103, "Amit", 35)
        };

        foreach (Student student in students)
        {
            student.Display();
        }
    }
}

Example output:

Roll Number: 101
Name: Rahul
Marks: 85
Result: Pass
---------------------
Roll Number: 102
Name: Priya
Marks: 92
Result: Pass
---------------------
Roll Number: 103
Name: Amit
Marks: 35
Result: Fail
---------------------

What This Project Demonstrates

  • The parameterized constructor requires a roll number, name, and marks.

  • Constructor validation rejects invalid input.

  • Read-only properties prevent callers from changing the initialized student details through ordinary property assignment.

  • GetResult() calculates the student's result.

  • A List<Student> stores multiple student objects.

  • The foreach loop displays each student's details.

This example demonstrates why constructors are useful for keeping object initialization consistent and predictable.

16. Common Constructor Mistakes

Mistake 1: Giving a constructor a return type

Incorrect:

public void Student()
{
}

This is a method, not a constructor.

Correct:

public Student()
{
}

Mistake 2: Assuming a parameterless constructor always exists

If you declare a parameterized constructor, the compiler does not automatically add the implicit parameterless constructor.

class Student
{
    public Student(string name)
    {
    }
}

This will not compile:

Student student = new Student();

Add a parameterless constructor if that creation pattern is required.

Mistake 3: Repeating initialization logic

Writing the same initialization code in multiple constructors makes maintenance harder. Consider constructor chaining with this(...).

Mistake 4: Ignoring input validation

A constructor that accepts invalid values can create objects that are difficult to use correctly. Validate important inputs according to the class's requirements.

Mistake 5: Confusing static and instance constructors

An instance constructor initializes an object. A static constructor initializes static state for a type. They have different purposes and execution rules.

Mistake 6: Assuming a copy-style constructor performs a deep copy

Copying properties that contain references may result in two objects sharing the same referenced data. Decide whether a shallow or deep copy is appropriate.

Mistake 7: Performing excessive work in constructors

Constructors should usually establish valid initial state. Complex network requests, long-running tasks, and operations that need explicit error handling are often better handled by separate methods or factory patterns.

17. Best Practices for Constructors in C#

  1. Initialize required data: Ensure objects start with the information they need.

  2. Validate arguments: Reject invalid values at the object's creation boundary.

  3. Use meaningful parameter names: Names such as studentName and initialBalance make code easier to understand.

  4. Use constructor chaining: Centralize common initialization logic.

  5. Keep constructors focused: Avoid unrelated business operations during object creation.

  6. Use appropriate access modifiers: Choose public, private, or protected access based on the design.

  7. Prefer immutable state where appropriate: Read-only properties can help preserve object validity.

  8. Handle nullable values intentionally: Decide whether a reference is required or whether null is a valid value.

  9. Avoid unnecessary constructors: Add constructor overloads only when they support meaningful creation scenarios.

  10. Document non-obvious behavior: Explain important initialization requirements and validation rules.

18. Practice Exercises

Exercise 1: Employee Constructor

Create an Employee class with Name, EmployeeId, and Salary. Initialize all three values through a parameterized constructor.

Exercise 2: Constructor Overloading

Create a Book class with constructors that accept no arguments, only a title, or a title and author.

Exercise 3: Constructor Chaining

Create a Product class with multiple constructors and use this(...) to reduce repeated initialization code.

Exercise 4: Copy-Style Constructor

Create a Student class with a constructor that accepts another Student and copies its property values.

Exercise 5: Static Constructor

Create an ApplicationInfo class that initializes a static application name and version.

Exercise 6: Input Validation

Create a BankAccount class that accepts an account holder and opening balance. Reject invalid values in the constructor.

19. Knowledge Check: Quiz

1. What is the primary purpose of a constructor?

A. To repeat a loop
B. To initialize an object
C. To return a value
D. To declare a namespace

2. Which statement about constructors is correct?

A. Every constructor must return void.
B. A constructor name matches its containing type.
C. Constructors must always be static.
D. Constructors are inherited like ordinary methods.

3. What is constructor overloading?

A. Defining multiple constructors with different parameter lists
B. Calling a method repeatedly
C. Creating only one object
D. Declaring a static variable

4. Which keyword can call another constructor in the same class?

A. base
B. return
C. this
D. static

5. What is the purpose of a static constructor?

A. To initialize static state for a type
B. To initialize every object separately
C. To return a string
D. To create a loop

6. If a class declares a parameterized constructor but no parameterless constructor, what happens to the implicit parameterless constructor?

A. It is always generated.
B. It is replaced by a static constructor.
C. It is not automatically generated.
D. The class cannot have objects.

Answers: 1-B, 2-B, 3-A, 4-C, 5-A, 6-C.

20. Frequently Asked Questions (FAQs)

Q1. What is a constructor in C#?

A constructor is a special member invoked during object creation to initialize an instance. It has the same name as its containing type and does not declare a return type.

Q2. What is the difference between a default and a parameterless constructor?

A default constructor commonly means the implicit parameterless constructor supplied by the compiler when no instance constructor is declared. A parameterless constructor is any constructor that accepts no arguments, including one explicitly written by the developer.

Q3. Can a class have multiple constructors?

Yes. A class can define multiple constructors with different parameter lists. This is called constructor overloading.

Q4. Can a constructor be private?

Yes. A private constructor prevents code outside the class from calling that constructor directly. It is useful in some factory-based designs and utility classes.

Q5. Can constructors return values?

No. Constructors do not declare return types. They initialize the instance or type as appropriate.

Q6. What is constructor chaining?

Constructor chaining means delegating initialization from one constructor to another. Use this(...) to call another constructor in the same type and base(...) to invoke a base-class constructor.

Q7. Is a copy constructor built into C#?

C# does not automatically provide a dedicated copy constructor for every class. You can implement a constructor that accepts an object of the same type and copies its values.

Q8. When does a static constructor run?

A static constructor runs automatically to initialize static state for a type. The runtime controls its execution according to the type's initialization semantics.

Q9. Can constructors be inherited?

No. Constructors are not inherited. A derived class declares its own constructors and can invoke a base-class constructor.

Q10. What is the difference between a constructor and an object initializer?

A constructor is invoked as part of creating an instance. An object initializer assigns accessible fields or properties after the constructor runs.

Conclusion

Constructors are essential for creating objects with predictable and valid initial state in C#. You have learned how parameterless and parameterized constructors work, how to overload and chain constructors, how derived classes invoke base constructors, and how static and private constructors support different design requirements.

By applying constructor validation, reducing duplicate initialization logic, and choosing appropriate access modifiers, you can write more reliable and maintainable C# applications.

←
Post 14 of 30
→