Primary Constructors with C#

To reduce the syntax needed when writing C# code, C# 9 added records with primary constructors. C# 10 then added records for structs. Using C# 12 you can create classes with primary constructors. This article explains the primary constructor syntax and shows the differences between class records, struct records, and normal classes.

Construction

Class Records

C# 9 introduced records – with either nominal or positional syntax options. While records add default implementation for equality, with the reduced syntax of positional records because the order of the properties is known, the C# compiler also creates deconstruction. The positional syntax makes use of primary constructors as shown with the following code snippet:

Class record with primary constructor

Here, the compiler creates properties with get and init accessors. Using the init accessor, it’s allowed to set the property with the constructor and the object initializer, but not afterwards.

Struct Records

C# 10 added syntax enhancements for structs including struct records. Here, primary constructors can be used as well. The following code snippet shows a struct record with a primary constructor:

Struct record with primary constructor

Contrary to class records, the compiler creates properties with get and set accessors.

Declaring the struct record as readonly as shown with the following code snippet, the compiler creates properties with get and init accessors – similar to class records:

Readonly struct record with primary constructor

Classes with Primary Constructors

Now with C# 12, primary constructors are available with all types, you can use them with normal classes and structs. The following code snippet shows a class with a primary constructor. The behavior is different to records. Here, the compiler uses capturing semantics which allows using this paramter from any member of the class. If the paramter is not used, the compiler can optimize the parameter away. This is a great candidate for dependency injection as shown with the following code snippet. There’s no need to create a variable and assign the parameter to the variable.

C# 12 class with primary constructor

> Captures were introduced in C# with anonymous methods and later with lambda expressions. When inside a lambda expression a variable outside of the lambda expression is used, the compiler creates a capture where this variable can be used even if the variable would go out of scope. In this scenario for the capture, also the term closure is used.

What about Properties?

Yes, you can have properties!

Not needed with records because the properties are created implicitly; to use properties with primary constructors in classes, you can add properties and reference the captured parameters as shown with the following code snippet:

C# 12 Primary constructor and properties

What about inheritance?

Yes, you can have inheritance!

Of course this is not possible with structs, but with classes and record classes. The following code snippet shows a class with a primary constructor and inheritance. Defining a primary constructor with the Rectangle class, invoke the constructor of the Shape base class by specifying the parameters with the base class name:

Primary constructor with inheritance

What about multiple constructors?

Yes, you can have multiple constructors!

You can have multiple constructors with different parameters. Specifying an addtional constructor, finally the primary constructor needs to be invoked as shown in the following code snippet:

Multiple constructors

Take away

With every version of C# we get new productivity features, there’s no need to write boilerplate code. First introduced with records, primary constructors are a great example for this. Of course, records offer more functionality than just primary constructors. Adding primary constructors to classes and structs, more scenarios are possible where the syntax can be reduced – for example with dependency injection.

Enjoy learning and programming!

Christian

If you enjoyed this article, I’m thankful if you support me with a coffee. Thanks!

Buy Me A Coffee

More Information

More information about programming Web API Services is available in my book and my workshops.

C# 9 – Positional or Nominal Records

Primary constructors with capturing semantics

Attributes on primary ctors

Primary constructor bodies, generating public properties

Read more about records and primary constructors in my book Professional C# and .NET – 2021 Edition

See Chapter 3, "Classes, Records, Structs, and Tuples".

Trainings

Sample source code

Photo 5180271 / Construction © Adisa | Dreamstime.com

5 thoughts on “Primary Constructors with C#

  1. The last paragraph under the heading “Class Records” reads as follows: “Here, the compiler creates properties with get and init accessors. The init accessor doesn’t allow to set the property with the constructor and the object initializer, but not afterwards. Of course you can also add a code block.”

    Should the second sentence actually read, “The init accessor *allows* to set the property with the constructor and the object initializer, but not afterwards. “?

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.