Everything about Primary constructors in C# 12 | Biggest update of DotNet 8.0

Primary constructors are added in C# 12 and this is a new way of creating the constructor of a class.

Primary constructor is the biggest update from dotnet 8.0 i.e. C# 12. In this post, we will learn everything about the Primary constructor in C# 12.

How we were used to working without a Primary Constructor?

Consider we are having an Employee class. This class has a method FullName() and the job of this method is to return the Full name of the employee.

If you will notice we also have one constructor that has two parameters firstName & lastName

Here is the code

class Employee
{
    private readonly string firstName;
    private readonly string lastName;

    public Employee(string firstName, string lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public string FullName()
    {
        return $"Full name  = {this.firstName} {this.lastName}";
    }
}

What is wrong with this old way of writing code with normal constructors?

Well, there is nothing wrong but if you focus on the above code then you will find that we have some duplicate code. This is what I mean to say:

  • We have the value in constructor parameters but still have to create separate fields or properties to use them in this class.
  • Because we have separate fields, we have to write the code to assign these parameters to the fields.
  • Now think you have 5 or 10 dependencies in your C# Class then you will have to write approximately 20 lines of code just to use the parameter values.

What do we want to achieve with Primary Constructors in C#?

By using the primary constructor we want to remove the unnecessary code from the class and make it more readable.

Let’s see how to use Primary Constructor in our C# Class.

How to use Primary Constructor in C# ?

This is how we can use the Primary constructor in C#

class Employee(string firstName, string lastName)
{
    public string FullName()
    {
        return $"Full name  = {firstName} {lastName}";
    }
}

Wow. This is superb. Now the code is much more readable and we can use these parameters directly in the entire class.

  • We have added parentheses in front of the class name with the parameters.
  • The scope of these parameters is the entire class.

But What If I still want to assign the Primary Constructor Parameters value to field or Property?

Excellent question ๐Ÿ˜€. Assigning the primary constructor’s parameter value to a field or property is possible.

Let’s see the code:

class Employee(string firstName, string lastName)
{
    private readonly string firstName = firstName;
    private readonly string lastName = lastName;

    public string FullName()
    {
        return $"Full name  = {this.firstName} {this.lastName}";
    }
}
  • Create your property or field and assign the value directly to them.
  • Now you can not use the parameters anywhere. You have to use only the field or property to access its value.

Can I add validations to the primary constructor parameters before assigning them to the field or property?

Of course, you can add validation to the primary constructor parameter. Consider an example. Let’s say I want to assign the firstName to our field only if it has 5 characters. This is how you can do it.

class Employee(string firstName, string lastName)
{
    private readonly string firstName = firstName.Length >= 5 ? 
                                        firstName : 
                                        throw new Exception("There must be atleast 5 characters");

    private readonly string lastName = lastName;

    public string FullName()
    {
        return $"Full name  = {this.firstName} {this.lastName}";
    }
}

Using the same approach you can add validation on all your parameters.

Can we have multiple (more than one) Primary Constructor in a Class?

This is good that you are thinking about this concept more deeply. But the answer is No.

Primary constructor means that among all constructors there is one which is primary and whenever we need to create the instance of this class, we will have to pass the values to these parameters.

Can we have more than one constructor along with the Primary Constructors in C#?

A class in C# can have more than one constructor and this is true with primary constructors as well. But there is a small twist ๐Ÿคช

Let’s say I want to have two more constructors in this class. This is how we used to write the code:

class Employee(string firstName, string lastName)
{
    public Employee()
    {
            
    }

    public Employee(string firstName, string lastName, int salary)
    {

    }

    public string FullName()
    {
        return $"Full name  = {firstName} {lastName}";
    }
}

But, Here if you write your code like this then will get the following error:

error CS8862: A constructor declared in a type with parameter list must have 'this' constructor initializer.

How to fix error CS8862: A constructor declared in a type with parameter list must have ‘this’ constructor initializer?

First, Let’s talk about the reason for this error. See we have multiple constructors and out of them we are making one as Primary. This means in any case we have to provide the value to the Primary Constructor Value.

So to fix this error we will have to pass values to the primary constructor from our other constructors using this keyword. This is how you can do it

class Employee(string firstName, string lastName)
{
    public Employee() : this("", "")
    {

    }

    public Employee(string firstName, string lastName, int salary) : this(firstName, lastName)
    {

    }

    public string FullName()
    {
        return $"Full name  = {firstName} {lastName}";
    }
}

How to pass parameter values to the Parent class in the case of Primary Constructor in C#?

This is a valid case. In the earlier version, we used to pass the parameter values using base keyword. Let’s learn how to handle this situation.

There could be two possibilities with the parent class.

  • The parent class is using primary constructor
  • The parent class is using the normal constructor

Parent class code:

class ParentEmployee(string firstName)
{
}

class ParentEmployee
{
    public ParentEmployee(string firstName)
    {
    }
}

In both the cases this is how you can pass the values to the Parent class.

class Employee(string firstName, string lastName) : ParentEmployee(firstName)

And in case the Child class is not using the Primary Constructor and the Parent class is using the Primary Constructor then you can still use the base keyword. Here is an example:

class Employee : ParentEmployee
{
    public Employee() : base("")
    {
    }

    public Employee(string firstName, string lastName, int salary) : base(firstName)
    {
    }
}

How Primary Constructors are different than Records in C#?

If you also have this question in your mind then I really appreciate it because you are aware of C# new concepts.

Nitish Kaushik

Here is the difference between the Records Constructor and the Primary Constructor in C#.

In reality, Record parameters are properties and you can access them using objects to get or set the values. But the Primary Constructor parameters are not properties they are simply parameters and can not be accessed outside the scope of the class not even using the class object.

What will happen if you try to access them outside the scope of class:

Employee employee = new("", "");

// Not allowed
employee.firstName = "New Value";

You will get the following error

error CS1061: 'Employee' does not contain a definition for 'firstName' and no accessible extension method 'firstName' accepting a first argument of type 'Employee' could be found (are you missing a using directive or an assembly reference?)

Primary Constructor in C# video

Primary Constructor in C# 12

Do you have any other questions?

This is good to hear that you still have questions about the Primary Constructor in C#.

Feel free to ask your questions in the comment box below and I will answer them as soon as I can.

Thank you for reading. I really appreciate ๐Ÿ™‚