Question

How to Call a Base Class Constructor in C#

csharp.netinheritanceconstructor

Question

If a class inherits from a base class in C# and you want to pass values from the derived class constructor to the base class constructor, how do you do that?

For example, suppose you inherit from Exception and want to pass the message value to the base Exception constructor:

class MyExceptionClass : Exception
{
    public MyExceptionClass(string message, string extraInfo)
    {
        // How do you pass message to the base Exception constructor?
        base(message);
    }
}

The goal is to pass the message string to the base Exception class constructor correctly.

Short Answer

By the end of this page, you will understand how constructor chaining works in C#, how to call a base class constructor using : base(...), and why this is especially useful when creating custom exception classes and other derived types.

Concept

In C#, when you create an object from a derived class, the base part of that object must be initialized too. That means the base class constructor runs as part of object creation.

If the base class needs arguments, you must pass them in the constructor declaration, not from inside the constructor body. C# uses constructor initializer syntax for this:

public Child(string value) : base(value)
{
}

This matters because the base class must be constructed before the derived class constructor body runs. By the time execution enters the { ... } body of your derived constructor, base initialization has already happened.

For your Exception example, the correct approach is:

class MyExceptionClass : Exception
{
    public string ExtraInfo { get; }

    public MyExceptionClass(string message, string extraInfo) : base(message)
    {
        ExtraInfo = extraInfo;
    }
}

This passes message to Exception, while the derived class handles its own additional data.

Why this matters in real programming:

  • Many framework classes require constructor parameters.
  • You often extend base types while preserving their built-in behavior.
  • Custom exceptions, controllers, models, and service classes commonly use constructor chaining.
  • It keeps object initialization correct and predictable.

Mental Model

Think of building a house extension.

  • The base class is the original house.
  • The derived class is the new extension.
  • Before you can finish the extension, the original house must already exist.

So in C#, the base constructor is called first to build the base part of the object. Then the derived constructor finishes the rest.

base(...) is like saying: "First, build the original part using these materials, then I will add my own part."

Take Quiz

Syntax and Examples

Core syntax

Use : base(...) after the constructor signature:

public DerivedType(arg1, arg2) : base(baseArg1, baseArg2)
{
    // derived class setup
}

Basic example

using System;

class Person
{
    public string Name { get; }

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

class Employee : Person
{
    public int EmployeeId { get; }

    public Employee(string name, int employeeId) : base(name)
    {
        EmployeeId = employeeId;
    }
}

Explanation

  • Person requires a name.
  • Employee inherits from Person.
  • Employee passes name to the base constructor using : base(name).
  • Then it initializes its own property, EmployeeId.

Custom exception example

using System;

class MyExceptionClass : Exception
{
    public string ExtraInfo { get; }

    public MyExceptionClass(string message, string extraInfo) : base(message)
    {
        ExtraInfo = extraInfo;
    }
}

Why this works

  • Exception already knows how to store the message.
  • Your custom exception adds ExtraInfo.
  • : base(message) ensures the standard exception message behavior still works.

Passing multiple values to the base constructor

class Animal
{
    public string Name { get; }
    public int Age { get; }

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

class Dog : Animal
{
    public string Breed { get; }

    public Dog(string name, int age, string breed) : base(name, age)
    {
        Breed = breed;
    }
}

Step by Step Execution

Consider this example:

using System;

class Person
{
    public string Name { get; }

    public Person(string name)
    {
        Console.WriteLine("Person constructor running");
        Name = name;
    }
}

class Employee : Person
{
    public int Id { get; }

    public Employee(string name, int id) : base(name)
    {
        Console.WriteLine("Employee constructor running");
        Id = id;
    }
}

var employee = new Employee("Ava", 42);
Console.WriteLine(employee.Name);
Console.WriteLine(employee.Id);

What happens step by step

  1. new Employee("Ava", 42) starts creating an Employee object.
  2. C# sees : base(name) in the Employee constructor.
  3. It calls Person("Ava") first.
  4. Inside Person, Name is set to "Ava".
  5. The Person constructor finishes.
  6. Control returns to the Employee constructor body.
  7. Id is set to 42.
  8. The Employee object is fully created.

Output

Person constructor running
Employee constructor running
Ava
42

The important rule is:

  • Base constructor first
  • Derived constructor body second

That is why base(message); cannot appear as a normal statement inside the constructor body.

Real World Use Cases

Using base constructors appears in many practical C# scenarios:

Custom exceptions

class ValidationException : Exception
{
    public ValidationException(string message) : base(message)
    {
    }
}

Used when you want standard exception behavior plus your own exception type.

Reusing common initialization

class DbEntity
{
    public Guid Id { get; }

    public DbEntity(Guid id)
    {
        Id = id;
    }
}

class User : DbEntity
{
    public string Email { get; }

    public User(Guid id, string email) : base(id)
    {
        Email = email;
    }
}

Useful when multiple classes share common fields.

UI or framework classes

Some framework base classes need configuration values during construction. Derived classes pass those values upward.

API models and domain objects

A base class may enforce required state such as IDs, names, timestamps, or metadata. Derived classes add specialized data while still calling the base constructor.

Take Quiz

Real Codebase Usage

In real projects, developers commonly use base constructor calls in these patterns:

Passing required state upward

If the base class owns a piece of data, let the base class initialize it.

class AppError : Exception
{
    public AppError(string message) : base(message) { }
}

Keeping derived constructors small

Avoid repeating base setup logic in every child class.

class Entity
{
    public DateTime CreatedAt { get; }

    public Entity()
    {
        CreatedAt = DateTime.UtcNow;
    }
}

class Order : Entity
{
    public decimal Total { get; }

    public Order(decimal total) : base()
    {
        Total = total;
    }
}

Validation before storing local values

You can still validate arguments in the derived constructor body, but constructor chaining happens before the body runs. If the validation affects values passed to the base constructor, do it in the argument expression.

class ProductBase
{
    public string Name { get; }

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

class Product : ProductBase
{
    public Product(string name) : base(string.IsNullOrWhiteSpace(name) ? "Unknown" : name)
    {
    }
}

Exception class conventions

Custom exceptions often provide multiple constructors:

using System;

class MyExceptionClass : Exception
{
    public MyExceptionClass() { }

    public MyExceptionClass(string message) : base(message) { }

    public MyExceptionClass(string message, Exception innerException)
        : base(message, innerException) { }
}

This matches common .NET exception patterns.

Common Mistakes

1. Trying to call base(...) inside the constructor body

This is the mistake from the original question.

Incorrect

class MyExceptionClass : Exception
{
    public MyExceptionClass(string message)
    {
        base(message); // Invalid
    }
}

Correct

class MyExceptionClass : Exception
{
    public MyExceptionClass(string message) : base(message)
    {
    }
}

2. Forgetting that the base constructor runs first

Beginners sometimes expect derived fields to be available before base(...) runs.

class Base
{
    public Base(string value) { }
}

class Child : Base
{
    private string _text;

    public Child(string text) : base(_text) // Problem: instance field not ready here
    {
        _text = text;
    }
}

Use constructor parameters or static/helper expressions instead.

3. Not calling a required base constructor

If the base class has no parameterless constructor, you must supply the required arguments.

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

class Child : Parent
{
    public Child() // Error: no base constructor specified
    {
    }
}

Fix:

class Child : Parent
{
    public Child(string name) : base(name)
    {
    }
}

4. Duplicating data unnecessarily

If Exception already stores the message, you usually do not need your own separate MessageText field.

5. Creating incomplete custom exceptions

For production code, custom exceptions often include standard constructors such as message-only and message-plus-inner-exception constructors.

Comparisons

ConceptPurposeSyntaxWhen to use
base(...)Calls a base class constructorpublic Child() : base(...)When the parent class must be initialized
this(...)Calls another constructor in the same classpublic Child() : this(...)When you want to reuse constructor logic within the same class
base.MemberAccesses a base class method or propertybase.ToString()When you want the parent implementation
constructor bodyRuns derived class logic after base initialization{ ... }For setting up the child class

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

class Example
{
    public Example() : this("default")
    {
    }

    public Example(string name)
    {
    }
}
  • this(...) stays in the same class.
  • base(...) goes to the parent class.

base(...) vs base.Member

class Parent
{
    public virtual void Print() => Console.WriteLine("Parent");
}

class Child : Parent
{
    public override void Print()
    {
        base.Print();
        Console.WriteLine("Child");
    }
}
  • base.Print() calls a base method.
  • : base(...) calls a base constructor.
Take Quiz

Cheat Sheet

class Child : Parent
{
    public Child(string value) : base(value)
    {
    }
}

Rules

  • Use : base(...) after the constructor signature.
  • The base constructor runs before the derived constructor body.
  • You cannot call base(...) like a normal method inside {}.
  • If the base class has no parameterless constructor, you must call one of its existing constructors.
  • Use this(...) to call another constructor in the same class.

Exception example

class MyExceptionClass : Exception
{
    public MyExceptionClass(string message, string extraInfo) : base(message)
    {
        ExtraInfo = extraInfo;
    }

    public string ExtraInfo { get; }
}

Common pattern for custom exceptions

class MyExceptionClass : Exception
{
    public MyExceptionClass() { }
    public MyExceptionClass(string message) : base(message) { }
    public MyExceptionClass(string message, Exception innerException)
        : base(message, innerException) { }
}

Edge case

This is invalid:

public Child(string name)
{
    base(name); // invalid
}

FAQ

How do you call a base constructor in C#?

Use : base(arguments) after the derived constructor declaration.

public Child(string name) : base(name)
{
}

Can I call base() inside the constructor body?

No. Base constructors must be called using constructor initializer syntax, not as a statement inside the body.

What happens if I do not call a base constructor explicitly?

C# tries to call the parameterless base constructor automatically. If the base class does not have one, you get a compile-time error.

How do I pass a message to Exception from a custom exception?

Use:

public MyExceptionClass(string message) : base(message)
{
}

What is the difference between base(...) and this(...)?

  • base(...) calls a constructor in the parent class.
  • this(...) calls another constructor in the same class.

Should custom exceptions have multiple constructors?

Usually yes, especially in .NET codebases. Common constructors include parameterless, message-only, and message-plus-inner-exception.

Does the base constructor always run first?

Yes. The base constructor finishes before the derived constructor body runs.

Take Quiz

Mini Project

Description

Create a small C# example with a base class and a derived class that passes data to the base constructor. This project helps you practice constructor chaining in a realistic way by modeling an application-specific exception with extra context.

Goal

Build a custom exception class that passes its message to Exception and stores additional information in its own property.

Requirements

  1. Create a class that inherits from Exception.
  2. Add a constructor that accepts message and one extra value such as extraInfo.
  3. Pass message to the base Exception constructor using : base(message).
  4. Store the extra value in a public read-only property.
  5. Throw the exception and print both the standard message and the extra information.
Take Quiz

Keep learning

Related questions

View more