Introduction

In C#, constructors are special methods used to initialize an object when it is created. When a class has multiple constructors, you may need one constructor to reuse another instead of duplicating initialization logic.

C# provides two constructor-chaining keywords for this purpose:

Both are used for constructor chaining, but they work at different levels. The following Library System example shows how they work step by step.

Using this(...) to Chain Constructors in the Same Class

Consider a Book class. Every book has a title, while author and price are optional pieces of information.

Without constructor chaining, you could repeat the title initialization in every constructor. Using this(...) allows the constructors to reuse existing initialization logic.

Step 1: Create a Book Class

public class Book
{
    public string Title { get; }
    public string Author { get; }
    public decimal Price { get; }

    // Constructor 1: Only title
    public Book(string title)
    {
        Title = title;
        Console.WriteLine($"Book created: {Title}");
    }

    // Constructor 2: Title + Author
    public Book(string title, string author) : this(title)
    {
        Author = author;
        Console.WriteLine($"Book by {Author}");
    }

    // Constructor 3: Title + Author + Price
    public Book(string title, string author, decimal price) : this(title, author)
    {
        Price = price;
        Console.WriteLine($"Price: {Price:C}");
    }
}

The important part is the constructor declaration:

public Book(string title, string author) : this(title)

Here, this(title) tells C# to execute the Book(string title) constructor before executing the body of the current constructor.

Similarly:

public Book(string title, string author, decimal price) : this(title, author)

calls the two-parameter constructor first.

Step 2: Create Book Objects

var b1 = new Book("Clean Code");

var b2 = new Book(
    "Clean Architecture",
    "Robert C. Martin");

var b3 = new Book(
    "Refactoring",
    "Martin Fowler",
    45.50m);

Output

Book created: Clean Code

Book created: Clean Architecture
Book by Robert C. Martin

Book created: Refactoring
Book by Martin Fowler
Price: $45.50

For b3, the execution order is:

Book(title, author, price)
        ↓
this(title, author)
        ↓
this(title)
        ↓
Constructor body

This means the title initialization is written only once.

Why Use this(...)?

The primary benefit is avoiding duplicated constructor initialization logic.

For example, instead of writing:

public Book(string title, string author)
{
    Title = title;
    Author = author;
}

public Book(string title, string author, decimal price)
{
    Title = title;
    Author = author;
    Price = price;
}

you can reuse the existing constructor:

public Book(string title, string author, decimal price)
    : this(title, author)
{
    Price = price;
}

This makes the initialization flow easier to maintain.

Using base(...) to Call a Parent Constructor

Now suppose the library also provides digital books.

A DigitalBook is still a Book, so it needs the properties and initialization defined by Book. At the same time, it has additional properties such as file format and file size.

This is where base(...) is useful.

Step 1: Create a DigitalBook Class

public class DigitalBook : Book
{
    public string Format { get; }
    public double FileSizeMB { get; }

    public DigitalBook(
        string title,
        string author,
        decimal price,
        string format,
        double fileSize)
        : base(title, author, price)
    {
        Format = format;
        FileSizeMB = fileSize;

        Console.WriteLine(
            $"Digital format: {Format}, Size: {FileSizeMB}MB");
    }
}

The following part is responsible for calling the parent constructor:

: base(title, author, price)

It invokes this constructor from the Book class:

public Book(string title, string author, decimal price)

The Book constructor therefore initializes the inherited state before the DigitalBook constructor initializes its own properties.

Step 2: Create a DigitalBook Object

var ebook = new DigitalBook(
    "Domain-Driven Design",
    "Eric Evans",
    55m,
    "PDF",
    5.2);

Output

Book created: Domain-Driven Design
Book by Eric Evans
Price: $55.00
Digital format: PDF, Size: 5.2MB

The execution flow is:

DigitalBook constructor
        ↓
base(title, author, price)
        ↓
Book(title, author, price)
        ↓
this(title, author)
        ↓
this(title)
        ↓
DigitalBook constructor body

This demonstrates that constructor chaining can work across both inheritance and overloaded constructors.

this(...) vs base(...)

Although both keywords are used for constructor chaining, they have different purposes.

Feature

this(...)

base(...)

Calls

Another constructor

Parent-class constructor

Scope

Same class

Base class

Common purpose

Reuse initialization

Initialize inherited state

Used with inheritance

Not required

Required when passing arguments to a base constructor

Location

Constructor initializer

Constructor initializer

For example:

public Book(string title, string author)
    : this(title)
{
    Author = author;
}

Here, this(title) calls another Book constructor.

In contrast:

public DigitalBook(...)
    : base(title, author, price)
{
}

Here, base(...) calls the Book constructor.

Important Rules

There are a few rules to remember when using constructor chaining.

this(...) and base(...) Are Constructor Initializers

They appear after the constructor declaration and before the constructor body:

public Book(string title, string author)
    : this(title)
{
    Author = author;
}

They are not regular statements that can be placed inside the constructor body.

This is invalid:

public Book(string title, string author)
{
    this(title); // Invalid
}

A Constructor Can Directly Specify Only One Initializer

A constructor cannot directly use both this(...) and base(...):

// Invalid
public DigitalBook(...)
    : this(...)
    : base(...)
{
}

However, constructors can form a chain indirectly. A derived constructor can call a base constructor, and that base constructor can itself call another constructor using this(...).

When Should You Use this(...)?

Use this(...) when multiple constructors in the same class share initialization logic.

For example:

public Book(string title)
{
    Title = title;
}

public Book(string title, string author)
    : this(title)
{
    Author = author;
}

This keeps common initialization in one place.

When Should You Use base(...)?

Use base(...) when a derived class needs to pass values to a parameterized constructor in its base class.

For example:

public DigitalBook(
    string title,
    string author,
    decimal price,
    string format)
    : base(title, author, price)
{
    Format = format;
}

The base class is responsible for initializing the properties it owns, while the derived class initializes its own additional state.

Common Mistakes

Repeating Initialization Instead of Using this(...)

If several constructors initialize the same properties, repeating the code can make maintenance harder.

Prefer constructor chaining where it makes the initialization flow clearer.

Forgetting That the Base Constructor Runs First

When using inheritance, the base-class constructor is executed before the derived-class constructor body.

For example:

public DigitalBook(...)
    : base(title, author, price)
{
    Format = "PDF";
}

The Book initialization happens before Format is assigned.

Creating Too Many Constructor Overloads

Constructor chaining is useful, but a class with many combinations of optional parameters can become difficult to understand.

For complex object creation, consider alternatives such as:

The appropriate choice depends on the complexity of the object and its initialization rules.

Complete Example

The following example combines this(...) and base(...):

using System;

public class Book
{
    public string Title { get; }
    public string Author { get; }
    public decimal Price { get; }

    public Book(string title)
    {
        Title = title;
        Console.WriteLine($"Book created: {Title}");
    }

    public Book(string title, string author)
        : this(title)
    {
        Author = author;
        Console.WriteLine($"Book by {Author}");
    }

    public Book(string title, string author, decimal price)
        : this(title, author)
    {
        Price = price;
        Console.WriteLine($"Price: {Price:C}");
    }
}

public class DigitalBook : Book
{
    public string Format { get; }
    public double FileSizeMB { get; }

    public DigitalBook(
        string title,
        string author,
        decimal price,
        string format,
        double fileSize)
        : base(title, author, price)
    {
        Format = format;
        FileSizeMB = fileSize;

        Console.WriteLine(
            $"Digital format: {Format}, Size: {FileSizeMB}MB");
    }
}

public class Program
{
    public static void Main()
    {
        var book = new Book(
            "Clean Code",
            "Robert C. Martin",
            45.50m);

        Console.WriteLine();

        var ebook = new DigitalBook(
            "Domain-Driven Design",
            "Eric Evans",
            55m,
            "PDF",
            5.2);
    }
}

Output

Book created: Clean Code
Book by Robert C. Martin
Price: $45.50

Book created: Domain-Driven Design
Book by Eric Evans
Price: $55.00
Digital format: PDF, Size: 5.2MB

Key Takeaway

Constructor chaining helps keep object initialization consistent and reduces duplicated code.

A simple way to remember the difference is:

this(...) → My class → another constructor in my class

base(...) → Parent class → a constructor in my parent class

Understanding this distinction makes constructor-heavy classes easier to design, maintain, and extend.