Primary constructors, introduced in C# 12.0 (.NET 8.0), allow you to declare constructor parameters in the class declaration itself. These parameters automatically become field or property members of the class. This feature reduces ceremony for classes with simple initialization logic and brings the convenience of record-style initialization to regular classes.
Why it matters
- Dramatically reduces boilerplate for simple classes with constructor parameters.
- Improves readability by declaring and initializing state in one place.
- Works seamlessly with inheritance and other class features.
- Makes simple data-holding classes more concise without requiring full record syntax.
Cautions
- Primary constructor parameters are accessible throughout the class body but are not automatically properties; assign them to properties explicitly if you need public access.
- If you declare an explicit constructor, primary constructor parameters are no longer directly accessible unless you explicitly forward them.
- Inheritance requires careful handling; derived classes must call the base primary constructor via the explicit
: base(...)syntax. - Primary constructors only initialize what you explicitly assign; don’t assume automatic properties are created.
Declare and initialize properties inline
Primary constructors let you declare constructor parameters directly in the class declaration, automatically creating and initializing backing fields.
Valid since C# 12.0
Without var
public class Person
{
private string name;
private int age;
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
public string GetName() => name;
}
With var
public class Person(string name, int age)
{
private string Name => name;
private int Age => age;
public string GetName() => Name;
}
Record-like initialization without records
Primary constructors bring record-style initialization convenience to regular classes, reducing boilerplate while maintaining explicit class semantics.
Valid since C# 12.0
var person = new Person("Alice", 30);
Console.WriteLine(person);
public class Person(string name, int age)
{
public string Name { get; } = name;
public int Age { get; } = age;
public override string ToString() => $"{Name} ({Age} years old)";
}