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.
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:
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:
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:
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.
> 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:
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:
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:
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!

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
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".