ZetCode

C# constructor

last modified October 5, 2026

In this article we show how to work with constructors in the C# language.

A constructor is a special method that is called when an object is created. Classes, structs, and records have constructors. The purpose of a constructor is to initialize the state of an object.

A constructor does not return a value and it does not use the void keyword. It has the same name as the type. Constructors can be overloaded; that is, there can be multiple constructors with the same name but different parameters.

Constructors are not inherited, but the base-class constructor is always executed before the derived-class constructor. If we do not write any constructor for a class, C# provides an implicit parameterless constructor. Once we define any constructor, the implicit one is no longer supplied.

A constructor cannot be abstract. Constructors are called indirectly through the new operator and cannot be invoked like ordinary methods. Since C# 12, classes and structs can also declare a primary constructor, whose parameters are written directly after the type name.

C# constructor example

Constructors are used to initialize fields.

Program.cs
var name = "Lenka";
var dob = new DateTime(1990, 3, 5);

var u = new User(name, dob);
Console.WriteLine(u);

class User
{
    private DateTime Born;
    private string Name;

    public User(string Name, DateTime Born)
    {
        this.Name = Name;
        this.Born = Born;
    }

    public override string ToString() =>
        $"{this.Name} was born on {this.Born.ToShortDateString()}";
}

We have a constructor for the User class.

var u = new User(name, dob);

We create the User object, passing its constructor two values. This is the time when the constructor of the object is called.

public User(string Name, DateTime Born)
{
    this.Name = Name;
    this.Born = Born;
}

Inside the constructor, we initialize two fields: Name and Born. Since the names of the fields and the constructor parameters are the same, the this keyword is mandatory. It is used to refer to the fields of the class.

$ dotnet run
Lenka was born on 3/5/1990

The this keyword is not necessary if we use different names for the constructor parameters.

Program.cs
var name = "Lenka";
var dob = new DateTime(1990, 3, 5);

var u = new User(name, dob);
Console.WriteLine(u);

class User
{
    private DateTime Born;
    private string Name;

    public User(string _Name, DateTime _Born)
    {
        Name = _Name;
        Born = _Born;
    }

    public override string ToString() =>
        $"{this.Name} was born on {this.Born.ToShortDateString()}";
}

Since we used the _Name and _Born parameter names, which differ from the Name and Born fields, we can omit the this keyword.

C# default constructor

A default constructor is one that does not take any parameter.

If we do not provide any constructor, C# creates one by default that instantiates the object and sets the member variables to their default values.

Program.cs
var u = new User();

Console.WriteLine(string.IsNullOrEmpty(u.Name));
Console.WriteLine(string.IsNullOrEmpty(u.Occupation));
Console.WriteLine(u.Dob == DateTime.MinValue);

Console.WriteLine(u);

class User
{
    public string? Name { get; set; }
    public string? Occupation { get; set; }
    public DateTime Dob { get; set; }

    public override string ToString() =>
        $"User {{ {this.Name} {this.Occupation} {this.Dob} }}";
}

We have a User class; we do not provide our own constructor, so C# creates a default one. The default value for a reference type such as string is null, and for DateTime it is DateTime.MinValue.

$ dotnet run
True
True
True
User {   1/1/0001 12:00:00 AM }

C# overloaded constructor

Constructors can be overloaded.

Program.cs
var u1 = new User();
var u2 = new User("Tom");

class User
{
    public User()
    {
        Console.WriteLine("User is created");
    }

    public User(string name)
    {
        Console.WriteLine($"User {name} is created");
    }
}

We have two constructors in the User class. C# calls these constructors based on parameters that we pass to them.

If we provide a custom constructor, C# does not create a default one. We can explicitly create a default, no-parameter constructor.

var u1 = new User();

Here, the default, no-parameter constructor is called.

var u2 = new User("Tom");

Here, the second constructor which takes one parameter is called.

$ dotnet run
User is created
User Tom is created

C# expression-bodied constructor

We can create expression-bodied constructors. For short constructors they provide a more concise syntax.

Program.cs
var u1 = new User("John Doe", "gardener");
var u2 = new User("Roger Roe", "driver");

Console.WriteLine(u1);
Console.WriteLine(u2);

class User
{
    private string Name;
    private string Occupation;

    public User(string Name, string Occupation) =>
        (this.Name, this.Occupation) = (Name, Occupation);

    public override string ToString() =>
        $"User {{ {this.Name} {this.Occupation} }}";
}

We have a constructor with two parameters; the fields are assigned in an expression body.

public User(string Name, string Occupation) =>
    (this.Name, this.Occupation) = (Name, Occupation);

The this keyword is required because the parameter names shadow the fields.

C# constructor chaining

Constructor chaining is the ability of a class to call another constructor from a constructor. To call another constructor from the same class, we use the this keyword.

Program.cs
var c1 = new Circle(5);
var c2 = new Circle();

class Circle
{
    public Circle(int radius)
    {
        Console.WriteLine($"Circle, r={radius} is created");
    }

    public Circle() : this(1) { }
}

We have a Circle class. The class has two constructors: the first takes one parameter and the second does not take any parameter.

public Circle(int radius)
{
    Console.WriteLine($"Circle, r={radius} is created");
}

This constructor takes one parameter — the radius.

public Circle() : this(1) { }

This is the parameterless constructor. It calls the other constructor and passes it a default radius of 1.

$ dotnet run
Circle, r=5 is created
Circle, r=1 is created

The chained constructor runs first, so the constructor that is called with this completes before the body of the calling constructor.

C# base-class constructor

When a derived class is instantiated, the base-class constructor is always executed before the body of the derived-class constructor. If we do not specify one explicitly, the parameterless base constructor is called automatically.

Program.cs
var u1 = new User();

Console.WriteLine("---------------");

var u2 = new User("Tom");

class Base
{
    public Base()
    {
        Console.WriteLine("Base constructor called");
    }
}

class User : Base
{
    public User()
    {
        Console.WriteLine("User constructor called");
    }

    public User(string user)
    {
        Console.WriteLine($"User {user} created");
    }
}

The User class inherits from the Base class. Both constructors call the base-class constructor.

$ dotnet run
Base constructor called
User constructor called
---------------
Base constructor called
User Tom created

With the base keyword, we can specify which base-class constructor should be called when creating instances of the derived class.

Program.cs
var u1 = new User();

Console.WriteLine("---------------");

var u2 = new User("Tom");

class Base
{
    public Base()
    {
        Console.WriteLine("Base() called");
    }

    public Base(string name)
    {
        Console.WriteLine("Base(string name) called");
    }
}

class User : Base
{
    public User()
    {
        Console.WriteLine("User created");
    }

    public User(string name) : base(name)
    {
        Console.WriteLine($"User {name} created");
    }
}

Now the Base class has two constructors. We can specify which constructors to call with the base keyword.

public User(string name) : base(name)
{
    Console.WriteLine($"User {name} created");
}

We tell the constructor to call the base constructor that takes one parameter.

$ dotnet run
Base() called
User created
---------------
Base(string name) called
User Tom created

C# copy constructor

A constructor that creates an object by copying the state of another object is called a copy constructor. C# does not generate one automatically, so we write it as an ordinary constructor that takes an instance of the same type.

Program.cs
var u1 = new User("John Doe", "gardener");
var u2 = new User(u1);
u2.Name = "Roger Roe";

Console.WriteLine(u1);
Console.WriteLine(u2);

class User
{
    public string Name { get; set; }
    public string Occupation { get; set; }

    public User(string Name, string Occupation) =>
        (this.Name, this.Occupation) = (Name, Occupation);

    public User(User user)
    {
        this.Name = user.Name;
        this.Occupation = user.Occupation;
    }

    public override string ToString() =>
        $"User {{ {this.Name} {this.Occupation} }}";
}

The User class contains a copy constructor.

public User(User user)
{
    this.Name = user.Name;
    this.Occupation = user.Occupation;
}

The fields of the class are assigned values from the object passed as a parameter to the constructor.

$ dotnet run
User { John Doe gardener }
User { Roger Roe gardener }

C# private constructor

Other classes cannot create instances of a class that has only private constructors. Private constructors are generally used in classes that have only static members.

Program.cs
Console.WriteLine(MyMath.Pow(2));
Console.WriteLine(MyMath.Pow(2, 3));
Console.WriteLine(MyMath.Pow(2, 5));

// var mm = new MyMath();
// Console.WriteLine(mm.GetType());

class MyMath
{
    private MyMath() { }

    public static int Pow(int x, int y = 2)
    {
        int val = 1;

        for (int i = 0; i < y; i++)
        {
            val *= x;
        }

        return val;
    }
}

We have a MyMath class that contains only static members. It is designed to be used without creating an instance, and the private constructor enforces this.

$ dotnet run
4
8
32

C# static constructor

A static constructor is used to initialize static data or to perform an action that needs to be executed only once. It is called automatically before the first instance is created or before any static member is referenced. A static constructor cannot take parameters, cannot have an access modifier, and cannot be called directly.

Program.cs
var runner1 = new Runner(1);

Thread.Sleep(700);

var runner2 = new Runner(2);

Thread.Sleep(1100);

Console.WriteLine(runner1.Finish());
Console.WriteLine(runner2.Finish());

class Runner
{
    private static readonly DateTime StartTime;
    private long Id;

    static Runner() => StartTime = DateTime.Now;

    public Runner(long Id) => this.Id = Id;

    public string Finish()
    {
        DateTime EndTime = DateTime.Now;
        return $"Runner {this.Id} finished in {EndTime - StartTime}";
    }
}

We have a static, readonly variable called StartTime. It is initialized with a static constructor when the first Runner is created.

static Runner() => StartTime = DateTime.Now;

Once initialized, the static StartTime is available to all instances of Runner. The runtime guarantees that the static constructor runs only once, even when several threads create instances at the same time.

$ dotnet run
Runner 1 finished in 00:00:01.8267889
Runner 2 finished in 00:00:01.8900243

C# primary constructor

A primary constructor declares the constructor parameters directly in the type declaration. The parameters are in scope throughout the type, so they can be used to initialize fields and properties. Primary constructors were introduced in C# 12 and are available for classes and structs.

Program.cs
var c = new Circle(5.0);
Console.WriteLine($"radius: {c.Radius}, area: {c.Area():F2}");

class Circle(double radius)
{
    public double Radius { get; } = radius;

    public double Area() => Math.PI * Radius * Radius;
}

The Circle class has a primary constructor with a single parameter, radius. The parameter initializes the Radius property.

$ dotnet run
radius: 5, area: 78.54

A primary constructor can also pass arguments to a base-class constructor.

Program.cs
var e = new Employee("Jane Doe", "IT");
Console.WriteLine(e);

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

class Employee(string name, string department) : Person(name)
{
    public string Department { get; } = department;

    public override string ToString() => $"{Name} works in {Department}";
}

The Employee primary constructor forwards its name parameter to the Person primary constructor with the base call syntax.

$ dotnet run
Jane Doe works in IT

C# record constructor

A record is a reference type that provides built-in value equality. A positional record generates a public primary constructor, init-only properties, and a deconstructor from its parameter list.

Program.cs
var p = new Point(3, 5);
var q = p with { X = 10 };

Console.WriteLine(p);
Console.WriteLine(q);
Console.WriteLine(p == new Point(3, 5));

record Point(int X, int Y);

The Point record declares a primary constructor with the parameters X and Y. The compiler generates public properties with the same names.

$ dotnet run
Point { X = 3, Y = 5 }
Point { X = 10, Y = 5 }
True

The with expression creates a copy of a record and changes the specified properties. Because records implement structural equality, two records that hold the same values are considered equal.

C# struct constructor

Structs are value types and can have constructors as well. Inside a struct constructor, every field must be definitely assigned before the constructor returns.

Program.cs
var v = new Vector(3, 4);
Console.WriteLine(v);
Console.WriteLine($"length: {v.Length():F2}");

var d = default(Vector);
Console.WriteLine(d);

readonly struct Vector
{
    public double X { get; }
    public double Y { get; }

    public Vector(double x, double y)
    {
        X = x;
        Y = y;
    }

    public double Length() => Math.Sqrt(X * X + Y * Y);

    public override string ToString() => $"({X}, {Y})";
}

The Vector struct has a constructor that assigns both properties. The default expression shows that a struct always has an implicit parameterless constructor that produces a zero-initialized value. Since C# 10 we may also declare our own explicit parameterless struct constructor.

$ dotnet run
(3, 4)
length: 5.00
(0, 0)

Source

Constructors - C# programming guide
Static constructors - C# programming guide
Primary constructors - C# tutorial
Records - C# reference

In this article we have worked with constructors in C#.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all C# tutorials.